/******************************************************************************
 * @ CompanyName : Copyright (C), 2031,  xx Information Technology Co., Ltd.
 * @ FileName    : event_schedule_manage.c
 * @ Descripttion: event and schedule manage function
 * @ version     : 1.4
 * @ Author      : SunXin
 * @ Date        : 2023-06-05 11:39:26
 * @ LastEditTime: 2023-09-18 20:17:10
 * @ Chargelog   : 1.xxx
 ******************************************************************************/

/*版本说明
 *            V1.0
 *            说明：构建并测试事件计划的基本功能
 *            说明：添加自毁机制
 *            V1.1
 *            说明：考虑到计划和事件结束的动作要立即生效，修改结束接口
 *            （1）立即结束接口
 *            （2）延时结束接口
 *            （3）添加计划的暂停逻辑和接口
 *            V1.2
 *            说明：添加嵌套创建和嵌套删除的问题，A事件function中创建B事件或A事件function中删除B事件
 *            （1）添加对当前队列中A位置的追踪
 *            说明：在外部线程去访问删除和新建任务容易出现资源冲突的问题
 *            （1）在调度器执行的过程中上锁
 *            （2）所以在创建和删除时都加入阻塞和非阻塞的方式
 *            （3）如果阻塞的方式locked,内部改用非阻塞方式操作
 *            （4）添加新建的任务的队列，优化队列的使用方式
 *            V1.3
 *            说明：完善消息的接口
 *            V1.4
 *            说明：事件计划的target 中添加业务逻辑的config对象和sport对象
 *            说明：添加功能从事件计划队列寻找指定的任务计划指针用于数据访问
 *            V1.5
 *            说明：事件计划的 target 中时间添加 tick 提供非 os 调度可能

***********************************************************************************/
/***********************************************************************************/
//使用说明：（版本v1.0）
//(1)移植说明：
//包含文件包括：
//调度器实体文件：fun_event_schedule_manage.c和fun_event_schedule_manage.h
//调度器功能测试文件：fun_event_schedule_test.c和fun_event_schedule_test.h
//调度器初始化：在task初始化时需要调用ExtEsManageEventQueueInit();和EsManageScheduleQueueInit();
//调度器维护：在task秒事件中（tick）调用ExtEsManageEventQueueLoopProc();和ExtEsManageScheduleQueueLoopProc();

//(2)基本配置：
//基本配置在头文件中以宏定义的方式实现
//a.队列深度为 ES_EVENT_QUEUE_MAX_NUM 和 ES_SCHEDULE_QUEUE_MAX_NUM
//b.可配置的创建和删除缓冲队列深度 ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM 等
//c.事件类型为 ENUM_ES_EVENT_TARGET_TYPE_S （需要自定义事件类型）
//d.事件执行方式为 ENUM_ES_EVENT_TARGET_OP_S （按需扩展事件执行方式）
//e.计划类型为 ENUM_ES_SCHEDULE_TARGET_TYPE_S （需要自定义计划类型）
//f.计划执行方式为 ENU_ES_SCHEDULE_TARGET_OP_S（按需扩展计划执行方式）

//(3)使用说明：
//调度分为两种对象：“事件” 和 “计划”
//“事件”：理解为单一次的执行事件或者按tick循环执行的事件，由外部事件驱动从而创建
//"计划"：理解为需要多次，定时，不定时，执行的事件，由config文件中的配置在上电，复位，更改时创建

//事件的使用步骤：
//a.创建事件：ExtEsManageEventQueueCreateNewEvent,注意参数，参数将决定事件的执行过程
//b.自动执行,自动结束在调度器内部（非阻塞）
//c.手动结束事件调用 ExtEsManageEventQueueDelEventNoBlock非阻塞 / ExtEsManageEventQueueDelEventBlock阻塞
//d.消息传递 ExtEsManageEventMessageTransfer（未完成）

//计划的使用步骤：
//a.创建计划：ExtEsManageScheduleQueueCreateNewOne,注意参数，参数将决定计划的执行过程
//b.自动执行,自动结束在调度器内部（非阻塞）
//c.手动结束计划调用 ExtEsManageScheduleQueueDelOneNoBlock 非阻塞 / ExtEsManageScheduleQueueDelOneBlock阻塞
//d.消息传递 ExtEsManageScheduleMessageTransfer（未完成）


/***********************************************************************************/

/***********************************************************************************/
//                  Header reference           
/***********************************************************************************/
#include "event_schedule_manage.h"


/***********************************************************************************/
//                  macro definition           
/***********************************************************************************/
#if((PRINT_MODE_DEF_RTT == PRINT_CONFIG_MODE)&&(LOG_ON == SYSTEM_EVENT_SCHEDULE_MANAGE_LOG_EN))
    #define sys_es_printf(...)          SEGGER_RTT_printf(0,__VA_ARGS__)
#elif((PRINT_MODE_DEF_UART == PRINT_CONFIG_MODE)&&(LOG_ON == SYSTEM_EVENT_SCHEDULE_MANAGE_LOG_EN))
    #define sys_es_printf(...)          debug_info(__VA_ARGS__)
#else
    #include <stdio.h>
    #define LOCAL_DEBUG(...)            printf(__VA_ARGS__)
#endif


// Dynamic request macro definition
#ifdef _USE_RTOS_DEF_
    #define data_malloc         kos_malloc
    #define data_free           kos_free
#else
    #define data_malloc         malloc
    #define data_free           free
#endif

//Queue scheduling:type define
typedef struct
{
    bool m_blEventToEmpty;  //去空 true:需要执行，false：不需要执行
    bool m_blEventPriSort;  //优先级排序
    bool m_blScheToEmpty;   //去空
    bool m_blSchePriSort;   //优先级排序 
}STRUCT_ES_QUEUE_SORT_T;

//Queue scheduling:entity
STRUCT_ES_QUEUE_SORT_T g_m_es_sort;

/***********************************************************************************/
//                  variable definition           
/***********************************************************************************/
//sys config api
extern const STRUCT_SYSTEM_INTERNAL_API es_sys_api;

//internal:事件计划的创建删除操作
static void EsManageOpInit(void);
static bool EsManageOpAddEvent(STRUCT_ES_EVENT_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);
static bool EsManageOpDelEvent(ENUM_ES_EVENT_TARGET_TYPE_S del_type);
static bool EsManageOpAddSchedule(STRUCT_ES_SCHEDULE_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);
static bool EsManageOpDelSchedule(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);
static void EsManageOpCheckEvent(void);
static void EsManageOpCheckSchedule(void);

//事件计划的创建删除操作
static STRUCT_ES_OP_T g_es_op;

//事件计划的消息
//static bool EsManageMsgPush(STRUCT_ES_MSG_T*msg);
//static bool EsManageMsgProc(void);

//事件计划的消息
//static STRUCT_ES_MSG_OBJ_T g_msg_op;

//CORE事件队列
ENUM_ES_EVENT_STATE_T g_m_es_event[ES_EVENT_QUEUE_MAX_NUM];

//CORE计划队列
ENUM_ES_SCHEDULE_STATE_T g_m_es_schedule[ES_SCHEDULE_QUEUE_MAX_NUM];

/***********************************************************************************/
//                  Function declaration           
/***********************************************************************************/
//LOCK FLAG
static void EsManageOpLock(void);
static void EsManageOpUnLock(void);
static bool EsManageOpIsLocked(void);
//OP PROC
static void EsManageOpInit(void);

static void EsManageEventQueueStateProc(ENUM_ES_EVENT_STATE_T *current_event);
static void EsManageEventQueuePriSort(void);
static void EsManageEventQueueToEmptySort(void);
static bool EsManageEventQueueDelOneEvent(ENUM_ES_EVENT_STATE_T *current_event);
static bool ExtEsManageEventQueueFindIndex(ENUM_ES_EVENT_TARGET_TYPE_S del_type,uint16_t *index_num);

static void EsManageScheduleQueueStateProc(ENUM_ES_SCHEDULE_STATE_T *current_sche);
static void EsManageScheduleQueuePriSort(void);
static void EsManageScheduleQueueToEmptySort(void);
static bool EsManageScheduleQueueDelOneSche(ENUM_ES_SCHEDULE_STATE_T *current_sche);
static bool EsManageScheduleTargetCheck(STRUCT_ES_SCHEDULE_TARGET_T *p_target);
static bool ScheTargetTimeIsInForOpAll(ENUM_ES_SCHEDULE_STATE_T *p_sche);
static bool ScheTargetTimeIsInForOnce(ENUM_ES_SCHEDULE_STATE_T *p_sche);
static bool ScheTargetTimeIsInForLoopSingle(ENUM_ES_SCHEDULE_STATE_T *p_sche);
static bool ScheTargetTimeIsInForLoopContinue(ENUM_ES_SCHEDULE_STATE_T *p_sche);
static bool EsManageScheduleTargetContinueTimeAndDayIsIn(ENUM_ES_SCHEDULE_STATE_T *p_sche);
static bool ExtEsManageScheduleQueueFindIndex(ENUM_ES_SCHEDULE_TARGET_TYPE_S find_type,uint16_t *index_num);

//api part 
void ExtEsManageEventQueueInit(void);
bool ExtEsManageEventQueueDelEventBlock(ENUM_ES_EVENT_TARGET_TYPE_S del_type);
bool ExtEsManageEventQueueDelEventNoBlock(ENUM_ES_EVENT_TARGET_TYPE_S del_type);
bool ExtEsManageEventQueueCreateNewEvent(STRUCT_ES_EVENT_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);
bool ExtEsManageEventMessageTransferBlock(ENUM_ES_EVENT_TARGET_TYPE_S event_type,uint8_t* message_buf,uint32_t message_len);
bool ExtEsManageEventFindPoint(ENUM_ES_EVENT_TARGET_TYPE_S event_type,STRUCT_ES_EVENT_TARGET_T** get_point);
void ExtEsManageEventQueueLoopProc(void);

void EsManageScheduleQueueInit(void);
bool ExtEsManageScheduleQueueDelOneBlock(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);
bool ExtEsManageScheduleQueueDelOneNoBlock(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);
bool ExtEsManageScheduleQueueCreateNewOne(STRUCT_ES_SCHEDULE_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);
bool ExtEsManageScheduleMessageTransferBlock(ENUM_ES_SCHEDULE_TARGET_TYPE_S sche_type,uint8_t* message_buf,uint32_t message_len);
bool ExtEsManageScheduleFindPoint(ENUM_ES_SCHEDULE_TARGET_TYPE_S sch_type,STRUCT_ES_SCHEDULE_TARGET_T** get_point);
void ExtEsManageScheduleQueueLoopProc(void);
bool ExtEsManageScheduleQueueSetPause(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);
bool ExtEsManageScheduleQueueSetResume(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);

//void ExtEsManageDebugAllEs(void);

const STRUCT_EVENT_SCHEDULE_API event_sch_api = 
{
    //event
    .event_init = ExtEsManageEventQueueInit,
    .event_del_block = ExtEsManageEventQueueDelEventBlock,
    .event_del_no_block = ExtEsManageEventQueueDelEventNoBlock,
    .event_create = ExtEsManageEventQueueCreateNewEvent,
    .event_msg_send = ExtEsManageEventMessageTransferBlock,
    .event_msg_find = ExtEsManageEventFindPoint,
    .event_proc = ExtEsManageEventQueueLoopProc,

    //schedule
    .sch_init = EsManageScheduleQueueInit,
    .sch_del_block = ExtEsManageScheduleQueueDelOneBlock,
    .sch_del_no_block = ExtEsManageScheduleQueueDelOneNoBlock,
    .sch_create = ExtEsManageScheduleQueueCreateNewOne,
    .sch_msg_send = ExtEsManageScheduleMessageTransferBlock,
    .sch_msg_find = ExtEsManageScheduleFindPoint,
    .sch_set_pause = ExtEsManageScheduleQueueSetPause,
    .sch_set_resume = ExtEsManageScheduleQueueSetResume,
    .sch_proc = ExtEsManageScheduleQueueLoopProc,

    //test part
    .debug_print = NULL,//ExtEsManageDebugAllEs
};

/**
 ***************************************************************************
 * @name EsManageOpLock
 * @brief Inner Functions:Event plan queue operations are locked internally
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件计划队列操作时内部上锁
static void EsManageOpLock(void)
{
    g_es_op.m_blLock = true;
}

/**
 ***************************************************************************
 * @name EsManageOpLock
 * @brief Inner Functions:Internal unlock during event plan queue operation
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件计划队列操作时内部解锁
static void EsManageOpUnLock(void)
{
    g_es_op.m_blLock = false;
}

/**
 ***************************************************************************
 * @name EsManageOpIsLocked
 * @brief Inner Functions:Internal unlock during event plan queue operation
 * @parm[in] none
 *
 * @return true:lock false:unlock
 ***************************************************************************
 */
 //内部函数：事件计划队列锁是否处于已锁定状态
static bool EsManageOpIsLocked(void)
{
    if(true == g_es_op.m_blLock)
    {
        return true;
    }
    else
    {
        return false;
    }
}

//------------------------------事件计划的创建删除操作start---------------------------------------------
/**
 ***************************************************************************
 * @name EsManageOpInit
 * @brief Inner Functions:Initialization entry function for event plan operation state
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件计划操作状态的初始化入口函数
static void EsManageOpInit(void)
{
    memset(&g_es_op,0,sizeof(STRUCT_ES_OP_T));
    g_es_op.m_blLock = true;
    g_es_op.m_ReqEventCreate.m_blValid = false;
    for(uint16_t i=0;i<ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM;i++)
    {
        g_es_op.m_ReqEventCreate.m_struNewEvent[i].m_blValid = false;
    }
    g_es_op.m_ReqEventDel.m_blValid = false;
    g_es_op.m_ReqEventDel.m_enuOPNum = 0;

    g_es_op.m_ReqScheduleCreate.m_blValid = false;
    for(uint16_t i=0;i<ES_CREATE_SCHEDULE_REQ_QUEUE_MAX_NUM;i++)
    {
        g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i].m_blValid = false;
    }
    g_es_op.m_ReqScheduleDel.m_blValid = false;
    g_es_op.m_ReqScheduleDel.m_enuOPNum = 0;
    
    g_es_op.EsManageOpAddEventHandle = EsManageOpAddEvent;
    g_es_op.EsManageOpDelEventHandle = EsManageOpDelEvent;
    g_es_op.EsManageOpAddSchHandle = EsManageOpAddSchedule;
    g_es_op.EsManageOpDelSchHandle = EsManageOpDelSchedule;

    g_es_op.EsManageOpCheckEventHandle = EsManageOpCheckEvent;
    g_es_op.EsManageOpCheckSchHandle = EsManageOpCheckSchedule;

    g_es_op.m_blLock = false;
}

/**
 ***************************************************************************
 * @name EsManageOpAddEvent
 * @brief Inner Functions:The event queue cache creates a new event
 * @parm[in] p_target:target obj;set_pri:obj priority
 *
 * @return true:sucess false:faild
 ***************************************************************************
 */
 //内部函数：事件队列缓存创建一个新事件
static bool EsManageOpAddEvent(STRUCT_ES_EVENT_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri)
{
    LOCAL_DEBUG("ES_M::EsManageOpAddEvent \r\n");
    if(p_target != NULL)
    {
        //上一级函数做参数检查
        //find
        for(uint16_t i = 0;i < ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM;i++)
        {
            if(false == g_es_op.m_ReqEventCreate.m_struNewEvent[i].m_blValid)
            {
                memcpy(&(g_es_op.m_ReqEventCreate.m_struNewEvent[i]),p_target,sizeof(STRUCT_ES_EVENT_TARGET_T));
                g_es_op.m_ReqEventCreate.m_enuEventProi[i] = set_pri;
                g_es_op.m_ReqEventCreate.m_blValid = true;
                return true;
            }
            else
            {
                LOCAL_DEBUG("ES_M:: add event buf full\r\n");
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name EsManageOpDelEvent
 * @brief Inner Functions:The event queue cache deletes an event
 * @parm[in] del_type:dest obj type
 *
 * @return true:sucess false:faild
 ***************************************************************************
 */
 //内部函数：事件队列缓存删除一个事件
static bool EsManageOpDelEvent(ENUM_ES_EVENT_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::EsManageOpDelEvent \r\n");
    //上一级函数做参数检查
    //find
    if(g_es_op.m_ReqEventDel.m_enuOPNum < ES_DEL_EVENT_REQ_QUEUE_MAX_NUM)
    {
        g_es_op.m_ReqEventDel.m_enuOPType[g_es_op.m_ReqEventDel.m_enuOPNum] = del_type;
        g_es_op.m_ReqEventDel.m_enuOPNum ++;
        g_es_op.m_ReqEventDel.m_blValid = true;
        return true;
    }
    else
    {
        LOCAL_DEBUG("ES_M:: del event buf full\r\n");
    }
    return false;
}

/**
 ***************************************************************************
 * @name EsManageOpAddSchedule
 * @brief Inner Functions:The schedule queue cache creates a new schedule
 * @parm[in] p_target:target obj;set_pri:obj priority
 *
 * @return true:sucess false:faild
 ***************************************************************************
 */
 //内部函数：计划队列缓存创建一个新计划
static bool EsManageOpAddSchedule(STRUCT_ES_SCHEDULE_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri)
{
    LOCAL_DEBUG("ES_M::EsManageOpAddSchedule \r\n");
    if(p_target != NULL)
    {
        //上一级函数做参数检查
        //find
        for(uint16_t i = 0;i < ES_CREATE_SCHEDULE_REQ_QUEUE_MAX_NUM;i++)
        {
            if(false == g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i].m_blValid)
            {
                memcpy(&(g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i]),p_target,sizeof(STRUCT_ES_SCHEDULE_TARGET_T));
                g_es_op.m_ReqScheduleCreate.m_enuScheduleProi[i] = set_pri;
                g_es_op.m_ReqScheduleCreate.m_blValid = true;
                return true;
            }
            else
            {
                LOCAL_DEBUG("ES_M:: add Schedule buf full\r\n");
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name EsManageOpDelSchedule
 * @brief Inner Functions:Schedule queue cache deletes a schedule
 * @parm[in] del_type:dest del target obj
 *
 * @return true:sucess false:faild
 ***************************************************************************
 */
 //内部函数：计划队列缓存删除一个计划
static bool EsManageOpDelSchedule(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::EsManageOpDelSchedule \r\n");
    //上一级函数做参数检查
    //find
    if(g_es_op.m_ReqScheduleDel.m_enuOPNum < ES_DEL_SCHEDULE_REQ_QUEUE_MAX_NUM)
    {
        g_es_op.m_ReqScheduleDel.m_enuOPType[g_es_op.m_ReqScheduleDel.m_enuOPNum] = del_type;
        g_es_op.m_ReqScheduleDel.m_enuOPNum ++;
        g_es_op.m_ReqScheduleDel.m_blValid = true;
        return true;
    }
    else
    {
        LOCAL_DEBUG("ES_M:: del Schedule buf full\r\n");
    }
    return false;
}

/**
 ***************************************************************************
 * @name EsManageOpCheckEvent
 * @brief Inner Functions:Event create and delete operation functions
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件创建和删除操作函数
static void EsManageOpCheckEvent(void)
{
    //1.event create
    if(true == g_es_op.m_ReqEventCreate.m_blValid)
    {
        for(uint16_t i = 0;i < ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM;i++)
        {
            if(true == g_es_op.m_ReqEventCreate.m_struNewEvent[i].m_blValid)
            {
                //create new
                for(uint16_t j = 0;j<ES_EVENT_QUEUE_MAX_NUM;j++)
                {
                    if(true == g_m_es_event[j].m_blIsEmpty)
                    {
                        memset(&(g_m_es_event[j]),0,sizeof(ENUM_ES_EVENT_STATE_T));
                        g_m_es_event[j].m_blIsEmpty = false;
                        g_m_es_event[j].m_enuPriority = g_es_op.m_ReqEventCreate.m_enuEventProi[i];
                        memcpy(&(g_m_es_event[j].m_enuTarget),&(g_es_op.m_ReqEventCreate.m_struNewEvent[i]),sizeof(STRUCT_ES_EVENT_TARGET_T));
                        g_m_es_event[j].m_enuState = e_ES_EVENT_WAIT_START;
                        LOCAL_DEBUG("ES_M::unblock create successful index == %d\r\n",j);
                        //新建后要重新排列优先级
                        g_m_es_sort.m_blEventPriSort = true;
                        break;
                    }
                }
                //clean
                memset(&(g_es_op.m_ReqEventCreate.m_struNewEvent[i]),0,sizeof(STRUCT_ES_EVENT_TARGET_T));
                g_es_op.m_ReqEventCreate.m_struNewEvent[i].m_blValid = false;
                g_es_op.m_ReqEventCreate.m_enuEventProi[i] = e_ES_PRIORITY_LOW;
            }
        }
        g_es_op.m_ReqEventCreate.m_blValid = false;
    }
    
    //2.event del
    if(true == g_es_op.m_ReqEventDel.m_blValid)
    {
        for(uint16_t i = 0;i < ES_DEL_EVENT_REQ_QUEUE_MAX_NUM;i++)
        {
            if(e_ES_EVENT_TYPE_NONE != g_es_op.m_ReqEventDel.m_enuOPType[i])
            {
                //del
                for(uint16_t j = 0;j<ES_EVENT_QUEUE_MAX_NUM;j++)
                {
                    if((false == g_m_es_event[j].m_blIsEmpty)&&
                        (g_m_es_event[j].m_enuTarget.m_enuType == g_es_op.m_ReqEventDel.m_enuOPType[i]))
                    {
                        g_m_es_event[j].m_enuState = e_ES_EVENT_ALREADY_OVER;
                        LOCAL_DEBUG("ES_M::unblock set event to stop successful index == %d\r\n",j);
                        //新增阻塞结束，因为有些时候需要立即结束，保证数据的一致性，新增调度结束事件
                        //销毁事件要求及时，销毁在销毁被调函数接口中处理
                        if(NULL != g_m_es_event[j].m_enuTarget.EsEventStopHandle)
                        {
                            (*(g_m_es_event[j].m_enuTarget.EsEventStopHandle))((struct STRUCT_ES_EVENT_TARGET*)&(g_m_es_event[j].m_enuTarget));
                        }
                        //事件结束要销毁这个事件
                        EsManageEventQueueDelOneEvent(&(g_m_es_event[j]));
                        //延迟队列主动去空
                    }
                }
                //clean
                g_es_op.m_ReqEventDel.m_enuOPType[i] = e_ES_EVENT_TYPE_NONE;
                if(g_es_op.m_ReqEventDel.m_enuOPNum > 0)
                {
                    g_es_op.m_ReqEventDel.m_enuOPNum --;
                }
                else
                {
                    g_es_op.m_ReqEventDel.m_blValid = false;
                }
            }
        }
        g_es_op.m_ReqEventDel.m_enuOPNum = 0;
        g_es_op.m_ReqEventDel.m_blValid = false;
    }

    //队列去空
    if(true == g_m_es_sort.m_blEventToEmpty)
    {
        EsManageEventQueueToEmptySort();
        g_m_es_sort.m_blEventToEmpty = false;
        //ExtEsManageDebugAllEs();
    }
}

/**
 ***************************************************************************
 * @name EsManageOpCheckSchedule
 * @brief Inner Functions:schedule create and delete operation functions
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：计划创建和删除操作函数
static void EsManageOpCheckSchedule(void)
{
    //1.SCH create
    if(g_es_op.m_ReqScheduleCreate.m_blValid == true)
    {
        for(uint16_t i = 0;i < ES_CREATE_SCHEDULE_REQ_QUEUE_MAX_NUM;i++)
        {
            if(true == g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i].m_blValid)
            {
                //create new
                for(uint16_t j = 0;j<ES_SCHEDULE_QUEUE_MAX_NUM;j++)
                {
                    if(true == g_m_es_schedule[j].m_blIsEmpty)
                    {
                        memset(&(g_m_es_schedule[j]),0,sizeof(ENUM_ES_SCHEDULE_STATE_T));
                        g_m_es_schedule[j].m_blIsEmpty = false;
                        g_m_es_schedule[j].m_enuPriority = g_es_op.m_ReqScheduleCreate.m_enuScheduleProi[i];
                        memcpy(&(g_m_es_schedule[j].m_enuTarget),&(g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i]),sizeof(STRUCT_ES_SCHEDULE_TARGET_T));
                        g_m_es_schedule[j].m_enuState = e_ES_SCHEDULE_WAIT_OP_TIME;
                        LOCAL_DEBUG("ES_M::unblock sche create successful index == %d\r\n",j);
                        //新建后要重新排列优先级
                        g_m_es_sort.m_blSchePriSort = true;
                        break;
                    }
                }
                //clean
                memset(&(g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i]),0,sizeof(STRUCT_ES_SCHEDULE_TARGET_T));
                g_es_op.m_ReqScheduleCreate.m_struNewSchedule[i].m_blValid = false;
                g_es_op.m_ReqScheduleCreate.m_enuScheduleProi[i] = e_ES_PRIORITY_LOW;
            }
        }
        g_es_op.m_ReqScheduleCreate.m_blValid = false;
    }
    
    //2.SCH del
    if(true == g_es_op.m_ReqScheduleDel.m_blValid)
    {
        for(uint16_t i = 0;i < ES_DEL_SCHEDULE_REQ_QUEUE_MAX_NUM;i++)
        {
            if(e_ES_SCHEDULE_TYPE_NONE != g_es_op.m_ReqScheduleDel.m_enuOPType[i])
            {
                //del
                for(uint16_t j = 0;j<ES_SCHEDULE_QUEUE_MAX_NUM;j++)
                {
                    if((false == g_m_es_schedule[j].m_blIsEmpty)&&
                        (g_m_es_schedule[j].m_enuTarget.m_enuType == g_es_op.m_ReqScheduleDel.m_enuOPType[i]))
                    {
                        g_m_es_schedule[j].m_enuState = e_ES_SCHEDULE_ALREADY_OVER;
                        LOCAL_DEBUG("ES_M::unblock set Schedule to stop successful index == %d\r\n",j);
                        
                        //新增阻塞结束，因为有些时候需要立即结束，保证数据的一致性，新增调度结束事件
                        //销毁计划要求及时，销毁在销毁被调函数接口中处理
                        if(g_m_es_schedule[j].m_enuTarget.EsScheduleStopHandle != NULL)
                        {
                            (*(g_m_es_schedule[j].m_enuTarget.EsScheduleStopHandle))((struct STRUCT_ES_SCHEDULE_TARGET*)&(g_m_es_schedule[j].m_enuTarget));
                        }
                        //计划结束要销毁这个计划
                        EsManageScheduleQueueDelOneSche(&(g_m_es_schedule[j]));

                        //延迟主动排列去空一次
                    }
                }
                
                //clean
                g_es_op.m_ReqScheduleDel.m_enuOPType[i] = e_ES_SCHEDULE_TYPE_NONE;
                if(g_es_op.m_ReqScheduleDel.m_enuOPNum > 0)
                {
                    g_es_op.m_ReqScheduleDel.m_enuOPNum --;
                }
                else
                {
                    g_es_op.m_ReqScheduleDel.m_blValid = false;
                }
            }
        }
        g_es_op.m_ReqScheduleDel.m_enuOPNum = 0;
        g_es_op.m_ReqScheduleDel.m_blValid = false;
    }

    //主动排列去空一次
    if(true == g_m_es_sort.m_blScheToEmpty)
    {
        EsManageScheduleQueueToEmptySort();
        g_m_es_sort.m_blScheToEmpty = false;
        //ExtEsManageDebugAllEs();
    }
}

//------------------------------事件计划的创建删除操作end---------------------------------------------

//------------------------------事件计划的消息机制start---------------------------------------------
//
#if 0
/*****************************************************************************
 * 函 数 名 : EsManageMsgQueuePriSort
 * 函数功能 : 内部函数：消息队列优先排序
 * 输入参数 : 无
 * 输出参数 : 无
 * 返 回 值 : 无
*****************************************************************************/
static void EsManageMsgQueuePriSort(void)
{
    if(g_msg_op.m_u16MsgDataNum > 1)
    {
        LOCAL_DEBUG("ES_M::EsManageMsgQueuePriSort \r\n");
        uint16_t i;
        for (i = 1; i < g_msg_op.m_u16MsgDataNum; i++)
        {
            STRUCT_ES_MSG_T tmp;
            memcpy(&tmp,&(g_msg_op.m_struMsgData[i]),sizeof(STRUCT_ES_MSG_T));
            uint16_t inner = i;
            while ((inner > 0) && 
                    ((uint8_t)(g_msg_op.m_struMsgData[inner-1].m_enuMsgPrio) < (uint8_t)(tmp.m_enuMsgPrio)))
            {
                memcpy(&(g_msg_op.m_struMsgData[inner]),&(g_m_es_event[inner - 1]),sizeof(STRUCT_ES_MSG_T));
                inner--;
            }
            memcpy(&(g_msg_op.m_struMsgData[inner]),&tmp,sizeof(STRUCT_ES_MSG_T));
        }
    }
}

#if 0
/*****************************************************************************
 * 函 数 名  :  EsManageMsgInit
 * 函数功能  :  外部函数：消息的初始化入口函数
 * 输入参数  :无
 * 返 回 值  :  无
*****************************************************************************/
void EsManageMsgInit(void)
{
    memset(&g_msg_op,0,sizeof(STRUCT_ES_MSG_OBJ_T));
    
    g_msg_op.m_blOpLock = true;
    
    g_msg_op.m_u16MsgDataNum = 0;
    
    for(uint16_t i = 0;i < ES_MSG_QUEUE_MAX_NUM;i++)
    {
        g_msg_op.m_struMsgData[i].m_blValid = false;
        g_msg_op.m_struMsgData[i].m_enuMsgType = e_ES_MSG_UNKNOW_TYPE;
        g_msg_op.m_struMsgData[i].m_enuMsgPrio = e_ES_PRIORITY_LOW;
        g_msg_op.m_struMsgData[i].m_U32PayloadLen = 0;
        g_msg_op.m_struMsgData[i].m_u8PayLoadPbuf = NULL;
        
    }
    
    g_msg_op.EsMsgPushHandle = EsManageMsgPush;
    g_msg_op.EsMsgProcHandle = EsManageMsgProc;

    g_msg_op.m_blOpLock = false;
}
#endif

/*****************************************************************************
 * 函 数 名  :  EsManageMsgProc
 * 函数功能  :  外部函数：消息处理函数
 * 输入参数  :无
 * 返 回 值  :  无
*****************************************************************************/
void EsManageMsgExternProc(void)
{
    (*(g_msg_op.EsMsgProcHandle))();
}

/*****************************************************************************
 * 函 数 名  :  EsManageMsgExternPush
 * 函数功能  :  外部函数：消息压入函数
 * 输入参数  :无
 * 返 回 值  :  true(成功), false(错误)
*****************************************************************************/
bool EsManageMsgExternPush(STRUCT_ES_MSG_T*msg)
{
    if(msg!=NULL)
    {
        return (*(g_msg_op.EsMsgPushHandle))(msg);
    }
	return false;
}



/*****************************************************************************
 * 函 数 名  :  EsManageMsgPush
 * 函数功能  :  内部函数：压入一个消息
 * 输入参数  :msg:目标参数
 * 返 回 值  :  true(成功), false(错误)
*****************************************************************************/
#if 0
static bool EsManageMsgPush(STRUCT_ES_MSG_T*msg)
{
    LOCAL_DEBUG("ES_M::EsManageMsgPush \r\n");
    if(msg != NULL)
    {
        if((g_msg_op.m_u16MsgDataNum < ES_MSG_QUEUE_MAX_NUM)&&(false == g_msg_op.m_blOpLock))
        {
            g_msg_op.m_blOpLock = true;
            uint16_t index = g_msg_op.m_u16MsgDataNum;
            if((msg->m_U32PayloadLen > 0)&&
                (msg->m_u8PayLoadPbuf != NULL)&&
                (msg->m_enuMsgOpReq == e_ES_MSG_PAYLOAD_NEED_FREE))
            {
                g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf = (uint8_t*)data_malloc(sizeof(uint8_t)*msg->m_U32PayloadLen);
                if(NULL == g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf)
                {
                    LOCAL_DEBUG("ES_M::EsManageMsgPush malloc false!!! \r\n");
                    g_msg_op.m_blOpLock = false;
                    return false;
                }
            }
            memcpy(&(g_msg_op.m_struMsgData[index]),msg,sizeof(STRUCT_ES_MSG_T));
            g_msg_op.m_u16MsgDataNum++;

            //优先级排序
            EsManageMsgQueuePriSort();

            g_msg_op.m_blOpLock = false;

            return true;  
        }
    }
    return false; 
}

/*****************************************************************************
 * 函 数 名  :  EsManageMsgPopUp
 * 函数功能  :  内部函数：弹出一个消息
 * 输入参数  :  msg:创建的目标参数
 * 返 回 值  :  true(成功), false(错误)
*****************************************************************************/
static bool EsManageMsgProc(void)
{
    LOCAL_DEBUG("ES_M::EsManageMsgProc \r\n");
    if((g_msg_op.m_u16MsgDataNum > 0)&&(false == EsManageOpIsLocked())&&(false == g_msg_op.m_blOpLock))
    {
        g_msg_op.m_blOpLock = true;
        uint16_t index = 0;
        while(g_msg_op.m_u16MsgDataNum > 0)
        {
            if(true == g_msg_op.m_struMsgData[index].m_blValid)
            {
                switch(g_msg_op.m_struMsgData[index].m_enuMsgType)
                {
                    case e_ES_MSG_EVENT_TYPE:
                    {
                        for(uint8_t i = 0;i<ES_EVENT_QUEUE_MAX_NUM;i++)
                        {
                            //find event
                            if((g_m_es_event[i].m_blIsEmpty == false)&&
                                (g_m_es_event[i].m_enuTarget.m_enuType == g_msg_op.m_struMsgData[index].msg_obj_type.m_enuEventType))
                            {
                                if(g_m_es_event[i].m_enuTarget.EsEventMessageProcHandle != NULL)
                                {
                                    (*(g_m_es_event[i].m_enuTarget.EsEventMessageProcHandle))(&(g_m_es_event[i].m_enuTarget),g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf,g_msg_op.m_struMsgData[index].m_U32PayloadLen);
                                }
                                break;
                            }
                        }
                    }
                    break;
                    case e_ES_MSG_SCH_TYPE:
                    {
                        for(uint8_t i = 0;i<ES_SCHEDULE_QUEUE_MAX_NUM;i++)
                        {
                            //find sch
                            if((g_m_es_schedule[i].m_blIsEmpty == false)&&
                                (g_m_es_schedule[i].m_enuTarget.m_enuType == g_msg_op.m_struMsgData[index].msg_obj_type.m_enuSchType))
                            {
                                if(g_m_es_schedule[i].m_enuTarget.EsScheduleMessageProcHandle != NULL)
                                {
                                    (*(g_m_es_schedule[i].m_enuTarget.EsScheduleMessageProcHandle))(&(g_m_es_schedule[i].m_enuTarget),g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf,g_msg_op.m_struMsgData[index].m_U32PayloadLen);
                                }
                                break;
                            }
                        }
                    }
                    break;
                    default:
                        LOCAL_DEBUG("ES_M::MSG index = %d , MSG type = %d \r\n",index,g_msg_op.m_struMsgData[index].m_enuMsgType);
                        break;
                }
            }

            //clean msg
            if(e_ES_MSG_PAYLOAD_NEED_FREE == g_msg_op.m_struMsgData[index].m_enuMsgOpReq)
            {
                if(NULL != g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf)
                data_free(g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf);      
            }
            g_msg_op.m_struMsgData[index].m_blValid = false;
            g_msg_op.m_struMsgData[index].m_enuMsgType = e_ES_MSG_UNKNOW_TYPE;
            g_msg_op.m_struMsgData[index].m_enuMsgPrio = e_ES_PRIORITY_LOW;
            g_msg_op.m_struMsgData[index].m_enuMsgOpReq = e_ES_MSG_NO_PAYLOAD;
            g_msg_op.m_struMsgData[index].m_U32PayloadLen = 0;
            g_msg_op.m_struMsgData[index].m_u8PayLoadPbuf = NULL;

            if(g_msg_op.m_u16MsgDataNum > 0)
            {
                g_msg_op.m_u16MsgDataNum--;
            }
            index++; 
        }
        g_msg_op.m_blOpLock = false; 
    }
    return true;
}
#endif
#endif

//------------------------------事件计划的消息机制end-----------------------------------------------

//------------------------------事件core操作---------------------------------------------
/**
 ***************************************************************************
 * @name ExtEsManageEventQueueCreateNewEvent
 * @brief External call interface:The event queue creates a new event
 * @parm[in] p_target:dest obj;set_pri:op priority
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：事件队列创建一个新的事件
bool ExtEsManageEventQueueCreateNewEvent(STRUCT_ES_EVENT_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri)
{
    LOCAL_DEBUG("ES_M::EsManageEventQueueCreateNewEvent \r\n");
    if(p_target != NULL)
    {
        //1.参数检查
        if((true == p_target->m_blValid)&&
            (p_target->m_enuType > e_ES_EVENT_TYPE_NONE)&&
            (p_target->m_enuType < e_ES_EVENT_TYPE_MAX)&&
            (p_target->m_enuOP < e_ES_EVENT_OP_NONE))
        {
            if((e_ES_EVENT_OP_LONG_ON_TIME == p_target->m_enuOP)&&
                (p_target->m_u32SetTimeLong==0))
            {
                LOCAL_DEBUG("ES_M::e_ES_EVENT_OP_LONG_ON_TIME but set time is 0!! \r\n");
                return false;
            }

            if((NULL == p_target->EsEventStartHandle)&&
                (NULL == p_target->EsEventRunloopHandle)&&
                (NULL == p_target->EsEventMessageProcHandle)&&
                (NULL == p_target->EsEventStopHandle))
            {
                LOCAL_DEBUG("ES_M::event none op function, func point is NULL!! \r\n");
                return false;
            }
            //查看lock状态决定是否阻塞创建
            if(true == EsManageOpIsLocked())
            {
                if(true == g_es_op.EsManageOpAddEventHandle(p_target,set_pri))
                {
                    LOCAL_DEBUG("ES_M::event create lock true!! \r\n");
                }
                else
                {
                    LOCAL_DEBUG("ES_M::event create lock false!! \r\n");;
                }
                return false;
            }
            else
            {
                for(uint16_t i = 0;i < ES_EVENT_QUEUE_MAX_NUM;i++)
                {
                    if(true == g_m_es_event[i].m_blIsEmpty)
                    {
                        memset(&(g_m_es_event[i]),0,sizeof(ENUM_ES_EVENT_STATE_T));
                        g_m_es_event[i].m_blIsEmpty = false;
                        g_m_es_event[i].m_enuPriority = set_pri;
                        memcpy(&(g_m_es_event[i].m_enuTarget),p_target,sizeof(STRUCT_ES_EVENT_TARGET_T));
                        g_m_es_event[i].m_enuState = e_ES_EVENT_WAIT_START;
                        LOCAL_DEBUG("ES_M::create successful index == %d\r\n",i);
                        //新建后要重新排列优先级
                        g_m_es_sort.m_blEventPriSort = true;

                        //modify sunx 创建完以后要及时调度start 一次，loop中不再执行start,并直接进入running
                        if(NULL != g_m_es_event[i].m_enuTarget.EsEventStartHandle)
                        {
                            (*(g_m_es_event[i].m_enuTarget.EsEventStartHandle))((struct STRUCT_ES_EVENT_TARGET*)&(g_m_es_event[i].m_enuTarget));
                        }
                        g_m_es_event[i].m_enuState = e_ES_EVENT_RUNNING;
                        
                        return true;
                    }
                    else
                    {
                        //检查是否存在相同任务
                        if(g_m_es_event[i].m_enuTarget.m_enuType == p_target->m_enuType)
                        {
                            LOCAL_DEBUG("ES_M::is same event exist == %d\r\n",i);
                            return false;
                        }
                    }
                }
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageEventQueueDelEventBlock
 * @brief External call interface:Del an event queue blocks
 * @parm[in] del_type:dest obj
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：事件队列以阻塞的方式删除一个事件
bool ExtEsManageEventQueueDelEventBlock(ENUM_ES_EVENT_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::ExtEsManageEventQueueDelEventBlock ID==%d\r\n",del_type);
    if((del_type > e_ES_EVENT_TYPE_NONE)&&
       (del_type < e_ES_EVENT_TYPE_MAX))
    {
        //查看lock状态决定是否阻塞创建
        if(true == EsManageOpIsLocked())
        {
            if(true == ExtEsManageEventQueueDelEventNoBlock(del_type))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            for(uint8_t i = 0;i < ES_EVENT_QUEUE_MAX_NUM;i++)
            {
                if((false == g_m_es_event[i].m_blIsEmpty)&&
                    (g_m_es_event[i].m_enuTarget.m_enuType == del_type))
                {
                    g_m_es_event[i].m_enuState = e_ES_EVENT_ALREADY_OVER;
                    LOCAL_DEBUG("ES_M::set event to stop successful index == %d\r\n",i);
                    //新增阻塞结束，因为有些时候需要立即结束，保证数据的一致性，新增调度结束事件
                    //销毁事件要求及时，销毁在销毁被调函数接口中处理
                    if(g_m_es_event[i].m_enuTarget.EsEventStopHandle != NULL)
                    {
                        (*(g_m_es_event[i].m_enuTarget.EsEventStopHandle))((struct STRUCT_ES_EVENT_TARGET*)&(g_m_es_event[i].m_enuTarget));
                    }
                    //事件结束要销毁这个事件
                    EsManageEventQueueDelOneEvent(&(g_m_es_event[i]));
                    //队列主动去空一次
                    
                    //队列去空
                    if(true == g_m_es_sort.m_blEventToEmpty)
                    {
                        EsManageEventQueueToEmptySort();
                        g_m_es_sort.m_blEventToEmpty = false;
                        //ExtEsManageDebugAllEs();
                    }
                    return true;
                }
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageEventQueueDelEventNoBlock
 * @brief External call interface:Del an event queue noblock
 * @parm[in] del_type:dest obj
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：  事件队列以非阻塞方式删除一个事件
bool ExtEsManageEventQueueDelEventNoBlock(ENUM_ES_EVENT_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::ExtEsManageEventQueueDelEventNoBlock ID==%d\r\n",del_type);
    if((del_type > e_ES_EVENT_TYPE_NONE)&&
       (del_type < e_ES_EVENT_TYPE_MAX))
    {
        if(true == g_es_op.EsManageOpDelEventHandle(del_type))
        {
            return true;
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name EsManageEventQueueDelOneEvent
 * @brief External call interface:Del an event queue noblock
 * @parm[in] current_event:dest obj point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：从事件队列中删除一个事件释放该事件位置
static bool EsManageEventQueueDelOneEvent(ENUM_ES_EVENT_STATE_T *current_event)
{
    if(NULL != current_event)
    {
        LOCAL_DEBUG("ES_M::EsManageEventQueueDelOneEvent type == %d\r\n",current_event->m_enuTarget.m_enuType);
        memset(current_event,0,sizeof(ENUM_ES_EVENT_STATE_T));
        current_event->m_blIsEmpty = true;
        current_event->m_enuTarget.m_blValid = false;
        current_event->m_enuTarget.EsEventStartHandle = NULL;
        current_event->m_enuTarget.EsEventRunloopHandle = NULL;
        current_event->m_enuTarget.EsEventMessageProcHandle = NULL;
        current_event->m_enuTarget.EsEventStopHandle = NULL;
        
        if(NULL != current_event->m_enuTarget.content_buf)
        {
            data_free(current_event->m_enuTarget.content_buf);
            current_event->m_enuTarget.content_buf = NULL;
        }
        
        LOCAL_DEBUG("ES_M::event Del successful \r\n");
        //新建后要重新排列去空
        g_m_es_sort.m_blEventToEmpty = true;
        return true;
    }
    else
    {
        LOCAL_DEBUG("ES_M::event Del pa error \r\n");
        return false;
    }
}

/**
 ***************************************************************************
 * @name EsManageEventQueueInit
 * @brief External call interface:The event queue is initialized
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
//外部调用接口：事件队列初始化
void ExtEsManageEventQueueInit(void)
{
    LOCAL_DEBUG("ES_M::ExtEsManageEventQueueInit \r\n");
    
    //1.初始化op状态
    EsManageOpInit();
    
    //2.清空事件队列
    memset(g_m_es_event,0,(ES_EVENT_QUEUE_MAX_NUM*sizeof(ENUM_ES_EVENT_STATE_T)));
    for(uint16_t i =0 ;i < ES_EVENT_QUEUE_MAX_NUM;i++)
    {
        g_m_es_event[i].m_enuTarget.m_blValid = false;
        g_m_es_event[i].m_blIsEmpty = true;
    }
    g_m_es_sort.m_blEventToEmpty = false;
    g_m_es_sort.m_blEventPriSort = false;
    
    //TODO::3.预留从设置中获取开关状态，构建事件
    
    //unlock op
    EsManageOpUnLock();
}

/**
 ***************************************************************************
 * @name ExtEsManageEventMessageTransferBlock
 * @brief External call interface:Event queue messaging (blocking processing)
 * @parm[in] event_type:event type;message_buf:msg point;message_len:msg len
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
//外部调用接口：事件队列消息传递(阻塞处理)
//说明：此接口静止在其它task调度，是即时调用event msg handle
bool ExtEsManageEventMessageTransferBlock(ENUM_ES_EVENT_TARGET_TYPE_S event_type,uint8_t* message_buf,uint32_t message_len)
{
    LOCAL_DEBUG("ES_M::ExtEsManageEventMessageTransfer type=%d,ID=%d\r\n",event_type,message_id);
    if((event_type > e_ES_EVENT_TYPE_NONE)&&
       (event_type < e_ES_EVENT_TYPE_MAX))
    {
        for(uint8_t i = 0;i<ES_EVENT_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_event[i].m_blIsEmpty)&&
                (g_m_es_event[i].m_enuTarget.m_enuType == event_type))
            {
                if(NULL != g_m_es_event[i].m_enuTarget.EsEventMessageProcHandle)
                {
                    (*(g_m_es_event[i].m_enuTarget.EsEventMessageProcHandle))(&(g_m_es_event[i].m_enuTarget),message_buf,message_len);                    
                }
                LOCAL_DEBUG("ES_M::message transfer to index == %d\r\n",i);
                return true;
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageEventFindPoint
 * @brief External call interface:Finds the specified task pointer from the event queue for data access
 * @parm[in] event_type:event type;get_point:target obj point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：从事件队列寻找指定的任务指针用于数据访问
 //注意：处于数据保护只返回target 而非event obj
bool ExtEsManageEventFindPoint(ENUM_ES_EVENT_TARGET_TYPE_S event_type,STRUCT_ES_EVENT_TARGET_T** get_point)
{
    LOCAL_DEBUG("ES_M::ExtEsManageEventFindPoint type=%d\r\n",event_type);
    
    if((NULL != get_point)&&(event_type > e_ES_EVENT_TYPE_NONE)&&(event_type < e_ES_EVENT_TYPE_MAX))
    {
        for(uint16_t i = 0;i < ES_EVENT_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_event[i].m_blIsEmpty)&&
                (g_m_es_event[i].m_enuTarget.m_enuType == event_type))
            {
                *get_point = &(g_m_es_event[i].m_enuTarget);
                LOCAL_DEBUG("ES_M::event find index == %d\r\n",i);
                return true;
            }
        }
        LOCAL_DEBUG("ES_M::event cant find \r\n");
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageEventQueueLoopProc
 * @brief External call interface:The event queue loops through each event
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //外部调用接口：事件队列循环处理每一个事件
void ExtEsManageEventQueueLoopProc(void)
{
    //LOCAL_DEBUG("ES_M::ExtEsManageSEventQueueLoopProc \r\n");
    //op lock
    EsManageOpLock();

    //首先进行事件缓存op
    g_es_op.EsManageOpCheckEventHandle();
    
    
    //优先级排列
    if(true == g_m_es_sort.m_blEventPriSort)
    {
        EsManageEventQueuePriSort();
        g_m_es_sort.m_blEventPriSort = false;
        //ExtEsManageDebugAllEs();
    }
    
    for(uint8_t i = 0;i < ES_EVENT_QUEUE_MAX_NUM;)
    {
        if((false == g_m_es_event[i].m_blIsEmpty)&&
            (true == g_m_es_event[i].m_enuTarget.m_blValid))
        {
            LOCAL_DEBUG("ES_M::event %d, type %d \r\n",i,g_m_es_event[i].m_enuTarget.m_enuType);
            
            //先备份该事件的事件名，用于执行后跟踪该事件的队列节点下标
            ENUM_ES_EVENT_TARGET_TYPE_S bak_type = g_m_es_event[i].m_enuTarget.m_enuType;
            
            //根据事件状态引导事件执行
            EsManageEventQueueStateProc(&(g_m_es_event[i]));
            
            //根据事件目标引导事件状态
            switch(g_m_es_event[i].m_enuTarget.m_enuOP)
            {
                case e_ES_EVENT_OP_ONCE:
                {
                    if((e_ES_EVENT_RUNNING == g_m_es_event[i].m_enuState)&&
                        (g_m_es_event[i].m_u32OpNumCount>=1))
                    {
                        g_m_es_event[i].m_enuState = e_ES_EVENT_WAIT_STOP;
                    }
                }
                    break;
                case e_ES_EVENT_OP_LOOP:
                {
                    //nothing
                }
                    break;
                case e_ES_EVENT_OP_LONG_ON_TIME:
                {
                    if((e_ES_EVENT_RUNNING == g_m_es_event[i].m_enuState)&&
                        (g_m_es_event[i].m_u32OpTimeSecCount >= g_m_es_event[i].m_enuTarget.m_u32SetTimeLong))
                    {
                        g_m_es_event[i].m_enuState = e_ES_EVENT_WAIT_STOP;
                    }
                }
                    break;
                default:
                {
                    LOCAL_DEBUG("ES_M::[%d]Event target op type error == %d \r\n",i,g_m_es_event[i].m_enuTarget.m_enuOP);
                }
                    break;
            }

            //寻找该事件的节点下标位置
            uint16_t find_index = 0;
            if(true == ExtEsManageEventQueueFindIndex(bak_type,&find_index))
            {
                i = (find_index+1);
            }
            else
            {
                //找不到该节点说明当前节点已经被删除了，i 不变
            }
        }
        else
        {
            i++;
        }
    }

    //队列去空
    if(true ==g_m_es_sort.m_blEventToEmpty)
    {
        EsManageEventQueueToEmptySort();
        g_m_es_sort.m_blEventToEmpty = false;
        //ExtEsManageDebugAllEs();
    }

    //op unlock
    EsManageOpUnLock();
}

/**
 ***************************************************************************
 * @name EsManageEventQueueStateProc
 * @brief Inner Functions:Event content status processing
 * @parm[in] current_event:current event point
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件内容状态处理
static void EsManageEventQueueStateProc(ENUM_ES_EVENT_STATE_T *current_event)
{
    //LOCAL_DEBUG("ES_M::EsManageEventQueueStateProc \r\n");
    if(NULL != current_event)
    {
        switch(current_event->m_enuState)
        {
            case e_ES_EVENT_WAIT_START:
            {
                //modify by sunx loop中不再循环start，在创建时直接执行start,并直接进入running
                /*
                if(current_event->m_enuTarget.EsEventStartHandle != NULL)
                {
                    (*(current_event->m_enuTarget.EsEventStartHandle))((struct STRUCT_ES_EVENT_TARGET*)&(current_event->m_enuTarget));
                }*/
                current_event->m_enuState = e_ES_EVENT_RUNNING;
                
            }
                break;
            case e_ES_EVENT_RUNNING:
            {
                if(NULL != current_event->m_enuTarget.EsEventRunloopHandle)
                {
                    (*(current_event->m_enuTarget.EsEventRunloopHandle))((struct STRUCT_ES_EVENT_TARGET*)&(current_event->m_enuTarget));
                }
                //时间和次数按操作的方式进行累加
                current_event->m_u32OpNumCount++;
                current_event->m_u32OpTimeSecCount++;
                
            }
                break;
            case e_ES_EVENT_WAIT_STOP:
            {
                //销毁事件延时非阻塞销毁在这里处理
                if(NULL != current_event->m_enuTarget.EsEventStopHandle)
                {
                    (*(current_event->m_enuTarget.EsEventStopHandle))((struct STRUCT_ES_EVENT_TARGET*)&(current_event->m_enuTarget));
                }
                //事件结束要销毁这个事件
                EsManageEventQueueDelOneEvent(current_event);
            }
                break;
            case e_ES_EVENT_ALREADY_OVER:
            {
                //防止阻塞的处理异常，不再调用该事件的结束处理，只是删除位置
                EsManageEventQueueDelOneEvent(current_event);
            }
                break;
            default:
            {
                LOCAL_DEBUG("ES_M::Event state error == %d \r\n",current_event->m_enuState);
            }
                break;
        }
    }
    else
    {
        LOCAL_DEBUG("ES_M::parameter error \r\n");
    }
}

/**
 ***************************************************************************
 * @name ExtEsManageEventQueueFindIndex
 * @brief Inner Functions:Event content status processing
 * @parm[in] type:dest find type;index_num:return index
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：  寻找事件在事件队列位置下标
static bool ExtEsManageEventQueueFindIndex(ENUM_ES_EVENT_TARGET_TYPE_S del_type,uint16_t *index_num)
{
    LOCAL_DEBUG("ES_M::ExtEsManageEventQueueFindIndex ID==%d\r\n",del_type);
    if((NULL != index_num)&&
        (del_type > e_ES_EVENT_TYPE_NONE)&&
       (del_type < e_ES_EVENT_TYPE_MAX))
    {
        *index_num = 0;
        for(uint16_t i = 0;i<ES_EVENT_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_event[i].m_blIsEmpty)&&
                (g_m_es_event[i].m_enuTarget.m_enuType == del_type))
            {
                LOCAL_DEBUG("ES_M::find event successful index == %d\r\n",i);
                *index_num = i;
                return true;
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name EsManageEventQueuePriSort
 * @brief Inner Functions:Event queue prioritization
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件队列优先排序
static void EsManageEventQueuePriSort(void)
{
    LOCAL_DEBUG("ES_M::EsManageEventQueuePriSort \r\n");

    uint16_t i;
    for (i = 1; i < ES_EVENT_QUEUE_MAX_NUM; i++)
    {
        ENUM_ES_EVENT_STATE_T tmp = g_m_es_event[i];
        uint16_t inner = i;
        if(false == tmp.m_blIsEmpty)
        {
            while((inner > 0) && 
                ((uint8_t)(g_m_es_event[inner-1].m_enuPriority) < (uint8_t)(tmp.m_enuPriority)))
            {
                g_m_es_event[inner] = g_m_es_event[inner - 1];
                inner--;
            }
            g_m_es_event[inner] = tmp;
        }
    }
    return;
}

/**
 ***************************************************************************
 * @name EsManageEventQueueToEmptySort
 * @brief Inner Functions:Empty-sorted event queue
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：事件队列去空排序
static void EsManageEventQueueToEmptySort(void)
{
    LOCAL_DEBUG("ES_M::EsManageEventQueueToEmptySort \r\n");
    ENUM_ES_EVENT_STATE_T temp_es_event[ES_EVENT_QUEUE_MAX_NUM] = {0};
    uint8_t temp_es_index = 0;
    uint16_t i = 0;
    for(i = 0;i < ES_EVENT_QUEUE_MAX_NUM;i++)
    {
        temp_es_event[i].m_enuTarget.m_blValid = false;
        temp_es_event[i].m_blIsEmpty = true;
    }
    
    for(i = 0;i < ES_EVENT_QUEUE_MAX_NUM;i++)
    {
        if(false == g_m_es_event[i].m_blIsEmpty)
        {
            memcpy(&(temp_es_event[temp_es_index]),&(g_m_es_event[i]),sizeof(ENUM_ES_EVENT_STATE_T));
            temp_es_index++;
        }
    }
    memcpy(g_m_es_event,temp_es_event,(ES_EVENT_QUEUE_MAX_NUM*sizeof(ENUM_ES_EVENT_STATE_T)));
}

/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/**
 ***************************************************************************
 * @name EsManageScheduleQueueInit
 * @brief External call interface:Schedule queue initialization
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //外部调用接口：计划队列初始化
void EsManageScheduleQueueInit(void)
{
    LOCAL_DEBUG("ES_M::EsManageScheduleQueueInit \r\n");
    //1.清空计划队列
    memset(g_m_es_schedule,0,(ES_SCHEDULE_QUEUE_MAX_NUM*sizeof(ENUM_ES_SCHEDULE_STATE_T)));
    for(uint16_t i = 0 ;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
    {
        g_m_es_schedule[i].m_enuTarget.m_blValid = false;
        g_m_es_schedule[i].m_blIsEmpty = true;
    }
    //2.从设置中获取开关状态，构建计划
    g_m_es_sort.m_blScheToEmpty = false;
    g_m_es_sort.m_blSchePriSort = false;

    //unlock op
    EsManageOpUnLock();
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueDelOneBlock
 * @brief External call interface:The schedule queue blocks a schedule
 * @parm[in] del_type:dest del schedule type
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：计划队列以阻塞的方式删除一个计划
bool ExtEsManageScheduleQueueDelOneBlock(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueDelOneBlock ID==%d\r\n",del_type);
    if((del_type > e_ES_SCHEDULE_TYPE_NONE)&&(del_type < e_ES_SCHEDULE_TYPE_MAX))
    {
        //查看lock状态决定是否阻塞创建
        if(true == EsManageOpIsLocked())
        {
            if(true == ExtEsManageScheduleQueueDelOneNoBlock(del_type))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
            {
                if((false == g_m_es_schedule[i].m_blIsEmpty)&&
                    (g_m_es_schedule[i].m_enuTarget.m_enuType == del_type))
                {
                    g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_ALREADY_OVER;
                    LOCAL_DEBUG("ES_M::set Schedule to stop successful index == %d\r\n",i);
                    
                    //新增阻塞结束，因为有些时候需要立即结束，保证数据的一致性，新增调度结束事件
                    //销毁计划要求及时，销毁在销毁被调函数接口中处理
                    if(NULL != g_m_es_schedule[i].m_enuTarget.EsScheduleStopHandle)
                    {
                        (*(g_m_es_schedule[i].m_enuTarget.EsScheduleStopHandle))((struct STRUCT_ES_SCHEDULE_TARGET*)&(g_m_es_schedule[i].m_enuTarget));
                    }
                    //计划结束要销毁这个计划
                    EsManageScheduleQueueDelOneSche(&(g_m_es_schedule[i]));

                    //主动排列去空一次
                    if(true == g_m_es_sort.m_blScheToEmpty)
                    {
                        EsManageScheduleQueueToEmptySort();
                        g_m_es_sort.m_blScheToEmpty = false;
                        //ExtEsManageDebugAllEs();
                    }
                    return true;
                }
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueDelOneNoBlock
 * @brief External call interface:The schedule queue noblock a schedule
 * @parm[in] del_type:dest del schedule type
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
//外部调用接口：计划队列以非阻塞的方式删除一个计划
bool ExtEsManageScheduleQueueDelOneNoBlock(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueDelOneNoBlock ID==%d\r\n",del_type);
    if((del_type > e_ES_SCHEDULE_TYPE_NONE)&&(del_type < e_ES_SCHEDULE_TYPE_MAX))
    {
        if(true == g_es_op.EsManageOpDelSchHandle(del_type))
        {
            return true;
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleMessageTransferBlock
 * @brief External call interface:Scheduled queue messaging (blocking processing)
 * @parm[in] del_type:sch type schedule type;message_buf:msg message_len:len
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：计划队列消息传递(阻塞处理)
 //说明：此接口静止在其它task调度，是即时调用event msg handle
bool ExtEsManageScheduleMessageTransferBlock(ENUM_ES_SCHEDULE_TARGET_TYPE_S sche_type,uint8_t* message_buf,uint32_t message_len)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleMessageTransfer type=%d,msglen=%d\r\n",sche_type,message_len);
    if((sche_type > e_ES_SCHEDULE_TYPE_NONE)&&(sche_type < e_ES_SCHEDULE_TYPE_MAX))
    {
        for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_schedule[i].m_blIsEmpty)&&
                (g_m_es_schedule[i].m_enuTarget.m_enuType == sche_type))
            {
                if(NULL != g_m_es_schedule[i].m_enuTarget.EsScheduleMessageProcHandle)
                {
                    (*(g_m_es_schedule[i].m_enuTarget.EsScheduleMessageProcHandle))(&(g_m_es_schedule[i].m_enuTarget),message_buf,message_len);
                }
                LOCAL_DEBUG("ES_M::sche message transfer to index == %d\r\n",i);
                return true;
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueSetPause
 * @brief External call interface:Scheduled set to pause
 * @parm[in] del_type:sch type schedule type
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：设置改计划为暂停
bool ExtEsManageScheduleQueueSetPause(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueSetPause ID==%d\r\n",del_type);
    if((del_type>e_ES_SCHEDULE_TYPE_NONE)&&(del_type<e_ES_SCHEDULE_TYPE_MAX))
    {
        for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_schedule[i].m_blIsEmpty)&&
                (g_m_es_schedule[i].m_enuTarget.m_enuType == del_type))
            {
                g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_ALREADY_OVER;
                LOCAL_DEBUG("ES_M::set Schedule to pause successful index == %d\r\n",i);
                
                if((g_m_es_schedule[i].m_enuState > e_ES_SCHEDULE_NONE)&&
                    (g_m_es_schedule[i].m_enuState < e_ES_SCHEDULE_INVERT_PAUSE))
                {
                    g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_INVERT_PAUSE;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueSetResume
 * @brief External call interface:Scheduled set to resume
 * @parm[in] del_type:sch type schedule type
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：设置改计划为恢复暂停
bool ExtEsManageScheduleQueueSetResume(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueSetResume ID==%d\r\n",del_type);
    if((del_type > e_ES_SCHEDULE_TYPE_NONE)&&(del_type < e_ES_SCHEDULE_TYPE_MAX))
    {
        for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_schedule[i].m_blIsEmpty)&&
                (g_m_es_schedule[i].m_enuTarget.m_enuType == del_type))
            {
                g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_ALREADY_OVER;
                LOCAL_DEBUG("ES_M::set Schedule to pause successful index == %d\r\n",i);
                
                if(e_ES_SCHEDULE_INVERT_PAUSE == g_m_es_schedule[i].m_enuState)
                {
                    //recheck
                    g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_NONE;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueCreateNewOne
 * @brief External call interface:The schedule queue creates a new Scheduled
 * @parm[in] del_type:sch type schedule obj;set_pri:priority type
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：计划队列创建一个新的计划
bool ExtEsManageScheduleQueueCreateNewOne(STRUCT_ES_SCHEDULE_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri)
{
    if(NULL != p_target)
    {
        LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueCreateNewOne type = %d\r\n",p_target->m_enuType);
        //1.参数检查
        if((true == p_target->m_blValid)&&
            (p_target->m_enuType > e_ES_SCHEDULE_TYPE_NONE)&&
            (p_target->m_enuType < e_ES_SCHEDULE_TYPE_MAX)&&
            (p_target->m_enuOP < e_ES_SCHEDULE_OP_NONE))
        {            
            //2.设定参数有效性检测
            if(true == EsManageScheduleTargetCheck(p_target))
            {
                //回调函数检查
                if((NULL == p_target->EsScheduleWaitHandle)&&
                    (NULL == p_target->EsScheduleRunloopHandle)&&
                    (NULL == p_target->EsScheduleMessageProcHandle)&&
                    (NULL == p_target->EsScheduleStopHandle))
                {
                    LOCAL_DEBUG("ES_M::schedule none op function, func point is NULL!! \r\n");
                    return false;
                }

                    //查看lock状态决定是否阻塞创建
                if(true == EsManageOpIsLocked())
                {
                    if(true == g_es_op.EsManageOpAddSchHandle(p_target,set_pri))
                    {
                        LOCAL_DEBUG("ES_M::SchHandle create lock true!! \r\n");
                    }
                    else
                    {
                        LOCAL_DEBUG("ES_M::SchHandle create lock false!! \r\n");
                    }
                    return false;
                }
                else
                {
                    for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
                    {
                        if(true == g_m_es_schedule[i].m_blIsEmpty)
                        {
                            memset(&(g_m_es_schedule[i]),0,sizeof(ENUM_ES_SCHEDULE_STATE_T));
                            g_m_es_schedule[i].m_blIsEmpty = false;
                            g_m_es_schedule[i].m_enuPriority = set_pri;
                            memcpy(&(g_m_es_schedule[i].m_enuTarget),p_target,sizeof(STRUCT_ES_SCHEDULE_TARGET_T));
                            g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_WAIT_OP_TIME;
                            LOCAL_DEBUG("ES_M::sche create successful index == %d\r\n",i);
                            //新建后要重新排列优先级
                            g_m_es_sort.m_blSchePriSort = true;
                            return true;
                        }
                        else
                        {
                            //检查是否存在相同计划
                            if(g_m_es_schedule[i].m_enuTarget.m_enuType == p_target->m_enuType)
                            {
                                LOCAL_DEBUG("ES_M::is same schedule exist == %d\r\n",i);
                                return false;
                            }
                        }
                    }
                }
            }
            else
            {
                LOCAL_DEBUG("ES_M::create new schedule ,but target check error!!!\r\n");
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleFindPoint
 * @brief External call interface:Finds the specified task pointer from the event queue for data access
 * @parm[in] del_type:sch type schedule obj;get_point:target point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //外部调用接口：从事件队列寻找指定的任务指针用于数据访问
 //注意：处于数据保护只返回target 而非event obj
bool ExtEsManageScheduleFindPoint(ENUM_ES_SCHEDULE_TARGET_TYPE_S sch_type,STRUCT_ES_SCHEDULE_TARGET_T** get_point)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleFindPoint type=%d,ID=%d\r\n",sch_type);
    
    if((NULL != get_point)&&(sch_type > e_ES_SCHEDULE_TYPE_NONE)&&(sch_type < e_ES_SCHEDULE_TYPE_MAX))
    {
        for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_schedule[i].m_blIsEmpty)&&
                (g_m_es_schedule[i].m_enuTarget.m_enuType == sch_type))
            {
                *get_point = &(g_m_es_schedule[i].m_enuTarget);
                LOCAL_DEBUG("ES_M::sch find index == %d\r\n",i);
                return true;
            }
        }
        LOCAL_DEBUG("ES_M::sch cant find \r\n");
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueLoopProc
 * @brief External call interface:The sch queue cycles through each sch
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //外部调用接口：计划队列循环处理每一个计划
void ExtEsManageScheduleQueueLoopProc(void)
{
    //LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueLoopProc \r\n");

    //lock op
    EsManageOpLock();

    //首先进行事件缓存op
    g_es_op.EsManageOpCheckSchHandle();
    
    //优先级排列
    if(true == g_m_es_sort.m_blSchePriSort)
    {
        EsManageScheduleQueuePriSort();
        g_m_es_sort.m_blSchePriSort = false;
        //ExtEsManageDebugAllEs();
    }
    
    for(uint16_t i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;)
    {
        if((false == g_m_es_schedule[i].m_blIsEmpty)&&
            (true == g_m_es_schedule[i].m_enuTarget.m_blValid))
        {
            LOCAL_DEBUG("ES_M::schedule %d op \r\n",i);

            //先备份该计划的计划名，用于执行后跟踪该事件的队列节点下标
            ENUM_ES_SCHEDULE_TARGET_TYPE_S bak_type = g_m_es_schedule[i].m_enuTarget.m_enuType;
            
            //根据计划状态引导计划执行
            EsManageScheduleQueueStateProc(&(g_m_es_schedule[i]));
            
            //根据计划目标引导计划状态
            switch(g_m_es_schedule[i].m_enuTarget.m_enuOP)
            {
                case e_ES_SCHEDULE_OP_ALL:
                {   
                    if(e_ES_SCHEDULE_INVERT_PAUSE == g_m_es_schedule[i].m_enuState)
                    {
                        //暂停中不处理
                    }
                    else if(0 == (g_m_es_schedule[i].m_enuTarget.m_struSetTime.u32SetOpInvertSec))
                    {
                        //无间隔时间
                        g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_RUNNING;
                        g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                        g_m_es_schedule[i].m_u32WaitTimeSecCount = 0;
                    }
                    else
                    {
                        if(e_ES_SCHEDULE_WAIT_OP_TIME == g_m_es_schedule[i].m_enuState)
                        {
                            if(true == ScheTargetTimeIsInForOpAll(&(g_m_es_schedule[i])))
                            {
                                g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_RUNNING;
                                g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                            }
                        }
                        else if(e_ES_SCHEDULE_RUNNING == g_m_es_schedule[i].m_enuState)
                        {
                            if(g_m_es_schedule[i].m_u32OpTimeSecCount > 0)
                            {
                                g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_WAIT_OP_TIME;
                                g_m_es_schedule[i].m_u32WaitTimeSecCount = 0;
                            }
                        }
                    }
                }
                    break;
                case e_ES_SCHEDULE_OP_ONCE:
                {
                    if(e_ES_SCHEDULE_INVERT_PAUSE == g_m_es_schedule[i].m_enuState)
                    {
                        //暂停中不处理
                    }
                    else if(e_ES_SCHEDULE_WAIT_OP_TIME == g_m_es_schedule[i].m_enuState)
                    {
                        if(true == ScheTargetTimeIsInForOnce(&(g_m_es_schedule[i])))
                        {
                            g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_RUNNING;
                            g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                        }
                    }
                    else if(e_ES_SCHEDULE_RUNNING == g_m_es_schedule[i].m_enuState)
                    {
                        if(g_m_es_schedule[i].m_u32OpTimeSecCount > 0)
                        {
                            g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_WAIT_STOP;
                            g_m_es_schedule[i].m_u32WaitTimeSecCount = 0;
                        }
                    }
                }
                    break;
                case e_ES_SCHEDULE_OP_LOOP_SINGLE:
                {
                    if(e_ES_SCHEDULE_INVERT_PAUSE == g_m_es_schedule[i].m_enuState)
                    {
                        //暂停中不处理
                    }
                    else if(e_ES_SCHEDULE_WAIT_OP_TIME == g_m_es_schedule[i].m_enuState)
                    {
                        if(true == ScheTargetTimeIsInForLoopSingle(&(g_m_es_schedule[i])))
                        {
                            g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_RUNNING;
                            g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                        }
                    }
                    else if(e_ES_SCHEDULE_RUNNING == g_m_es_schedule[i].m_enuState)
                    {
                        if(g_m_es_schedule[i].m_u32OpTimeSecCount > 0)
                        {
                            g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_WAIT_STOP;
                            g_m_es_schedule[i].m_u32WaitTimeSecCount = 0;
                        }
                    }
                }
                    break;
                case e_ES_SCHEDULE_OP_LOOP_CONTINUE:
                {
                    if(e_ES_SCHEDULE_INVERT_PAUSE == g_m_es_schedule[i].m_enuState)
                    {
                        //暂停中不处理
                    }
                    else if(true == ScheTargetTimeIsInForLoopContinue(&(g_m_es_schedule[i])))
                    {
                        switch(g_m_es_schedule[i].m_enuState)
                        {
                            case e_ES_SCHEDULE_WAIT_OP_TIME:
                            {
                                if(g_m_es_schedule[i].m_u32WaitTimeSecCount >= g_m_es_schedule[i].m_enuTarget.m_struSetTime.u32SetOpInvertSec)
                                {
                                    g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_RUNNING;
                                    g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                                }
                            }
                                break;
                            case e_ES_SCHEDULE_RUNNING:
                            {
                                if(g_m_es_schedule[i].m_u32OpTimeSecCount > 0)
                                {
                                    g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_INVERT_PAUSE;
                                    g_m_es_schedule[i].m_u32WaitTimeSecCount = 0;
                                }
                            }
                                break;
                            case e_ES_SCHEDULE_INVERT_PAUSE:
                            {
                                if(g_m_es_schedule[i].m_u32WaitTimeSecCount >= g_m_es_schedule[i].m_enuTarget.m_struSetTime.u32SetOpInvertSec)
                                {
                                    g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_RUNNING;
                                    g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                                }
                            }
                                break;
                            case e_ES_SCHEDULE_WAIT_STOP:
                            {
                                //nothing
                            }
                                break;
                            default:
                            {
                                LOCAL_DEBUG("ES_M::schedule %d op e_ES_SCHEDULE_OP_LOOP_CONTINUE type error =%d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_enuOP);
                            }
                        }
                    }
                    else
                    {
                        if(e_ES_SCHEDULE_WAIT_OP_TIME != g_m_es_schedule[i].m_enuState) 
                        {
                            g_m_es_schedule[i].m_enuState = e_ES_SCHEDULE_WAIT_OP_TIME;
                            g_m_es_schedule[i].m_u32OpTimeSecCount = 0;
                            g_m_es_schedule[i].m_u32WaitTimeSecCount = 0;
                        }
                        //其它状态不予处理
                    }
                }
                    break;
                default:
                {
                    LOCAL_DEBUG("ES_M::[%d]schedule target op type error == %d \r\n",i,g_m_es_schedule[i].m_enuTarget.m_enuOP);
                }
                    break;
            }

            //寻找该计划的节点下标位置
            uint16_t find_index = 0;
            if(true == ExtEsManageScheduleQueueFindIndex(bak_type,&find_index))
            {
                i = (find_index+1);
            }
            else
            {
                //找不到该节点说明当前节点已经被删除了，i 不变
            }
        }
        else
        {
            i++;
        }   
    }

    //排列去空
    if(true == g_m_es_sort.m_blScheToEmpty)
    {
        EsManageScheduleQueueToEmptySort();
        g_m_es_sort.m_blScheToEmpty = false;
        //ExtEsManageDebugAllEs();
    }

    //es test loop
    #ifdef ES_MANAGE_TEST_OPEN
    EsManageEventTestProc();
    #endif

    //unlock op
    EsManageOpUnLock();
}

/**
 ***************************************************************************
 * @name EsManageScheduleQueueStateProc
 * @brief Inner Functions:The sch queue cycles through each sch
 * @parm[in] current_sche:dest schedule point
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：  计划内容状态处理
static void EsManageScheduleQueueStateProc(ENUM_ES_SCHEDULE_STATE_T *current_sche)
{
    LOCAL_DEBUG("ES_M::EsManageScheduleQueueStateProc \r\n");
    if(NULL != current_sche)
    {
        switch(current_sche->m_enuState)
        {
            case e_ES_SCHEDULE_NONE:
            {
               //TODO::是否需要引入检测设置项
               current_sche->m_enuState = e_ES_SCHEDULE_WAIT_OP_TIME;
            }
                break;
            case e_ES_SCHEDULE_WAIT_OP_TIME:
            {
                if(NULL != current_sche->m_enuTarget.EsScheduleWaitHandle)
                {
                    (*(current_sche->m_enuTarget.EsScheduleWaitHandle))((struct STRUCT_ES_SCHEDULE_TARGET*)&(current_sche->m_enuTarget));
                }
                //等待条件满足后状态变化
                current_sche->m_u32WaitTimeSecCount++;
            }
                break;
            case e_ES_SCHEDULE_RUNNING:
            {
                if(NULL != current_sche->m_enuTarget.EsScheduleRunloopHandle)
                {
                    (*(current_sche->m_enuTarget.EsScheduleRunloopHandle))((struct STRUCT_ES_SCHEDULE_TARGET*)&(current_sche->m_enuTarget));
                }
                //时间和次数按操作的方式进行累加
                current_sche->m_u32OpTimeSecCount++;
            }
                break;
            case e_ES_SCHEDULE_INVERT_PAUSE:
            {
                //nothing
            }
                break;
            case e_ES_SCHEDULE_WAIT_STOP:
            {
                //销毁计划延时非阻塞销毁在这里处理
                if(NULL != current_sche->m_enuTarget.EsScheduleStopHandle)
                {
                    (*(current_sche->m_enuTarget.EsScheduleStopHandle))((struct STRUCT_ES_SCHEDULE_TARGET*)&(current_sche->m_enuTarget));
                }
                //计划结束要销毁这个计划
                EsManageScheduleQueueDelOneSche(current_sche);
            }
                break;
            case e_ES_SCHEDULE_ALREADY_OVER:
            {
                //防止阻塞的处理异常，不再调用该计划的结束处理，只是删除位置
                EsManageScheduleQueueDelOneSche(current_sche);
            }
                break;
            default:
            {
                LOCAL_DEBUG("ES_M::Schedule state error == %d \r\n",current_sche->m_enuState);
            }
                break;
        }
    }
    else
    {
        LOCAL_DEBUG("ES_M::parameter error \r\n");
    }
}

/**
 ***************************************************************************
 * @name EsManageScheduleQueuePriSort
 * @brief Inner Functions:Schedule queue priority sorting
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：计划队列优先级排序
static void EsManageScheduleQueuePriSort(void)
{
    LOCAL_DEBUG("ES_M::EsManageScheduleQueuePriSort \r\n");

    uint16_t i;
    for (i = 1; i < ES_SCHEDULE_QUEUE_MAX_NUM; i++)
    {
        ENUM_ES_SCHEDULE_STATE_T tmp = g_m_es_schedule[i];
        uint16_t inner = i;
        if(false == tmp.m_blIsEmpty)
        {
            while((inner > 0) && 
                ((uint8_t)(g_m_es_schedule[inner-1].m_enuPriority) < (uint8_t)(tmp.m_enuPriority)))
            {
                g_m_es_schedule[inner] = g_m_es_schedule[inner - 1];
                inner--;
            }
            g_m_es_schedule[inner] = tmp;
        }
    }
}

/**
 ***************************************************************************
 * @name EsManageScheduleQueueToEmptySort
 * @brief Inner Functions:Schedule queue emptying sort
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //内部函数：计划队列去空排序
static void EsManageScheduleQueueToEmptySort(void)
{
    LOCAL_DEBUG("ES_M::EsManageScheduleQueueToEmptySort \r\n");
    ENUM_ES_SCHEDULE_STATE_T temp_sche[ES_SCHEDULE_QUEUE_MAX_NUM] = {0};
    uint8_t temp_sche_index = 0;
    uint16_t i = 0;
    for(i = 0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
    {
        temp_sche[i].m_enuTarget.m_blValid = false;
        temp_sche[i].m_blIsEmpty = true;
    }
    
    for(i=0;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
    {
        if(false == g_m_es_schedule[i].m_blIsEmpty)
        {
            memcpy(&(temp_sche[temp_sche_index]),&(g_m_es_schedule[i]),sizeof(ENUM_ES_SCHEDULE_STATE_T));
            temp_sche_index++;
        }
    }
    memcpy(g_m_es_schedule,temp_sche,(ES_SCHEDULE_QUEUE_MAX_NUM*sizeof(ENUM_ES_SCHEDULE_STATE_T)));
}

/**
 ***************************************************************************
 * @name EsManageScheduleQueueDelOneSche
 * @brief Inner Functions:Removes an event from the event queue
 * @parm[in] current_sche:dest schedule
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：从事件队列中删除一个事件
static bool EsManageScheduleQueueDelOneSche(ENUM_ES_SCHEDULE_STATE_T *current_sche)
{
    if(NULL != current_sche)
    {
        LOCAL_DEBUG("ES_M::EsManageScheduleQueueDelOneSche type == %d\r\n",current_sche->m_enuTarget.m_enuType);
        memset(current_sche,0,sizeof(ENUM_ES_SCHEDULE_STATE_T));
        current_sche->m_blIsEmpty = true;
        LOCAL_DEBUG("ES_M::sch Del successful \r\n");
        //新建后要重新排列去空
        g_m_es_sort.m_blScheToEmpty = true;
        return true;
    }
    else
    {
        LOCAL_DEBUG("ES_M:: sche Del pa error \r\n");
        return false;
    }
}


/**
 ***************************************************************************
 * @name EsManageScheduleTargetCheck
 * @brief Inner Functions:Whether a schedule is on target time
 * @parm[in] p_target:dest schedule target
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：某个计划是否在目标时间内
static bool EsManageScheduleTargetCheck(STRUCT_ES_SCHEDULE_TARGET_T *p_target)
{
    if((true == p_target->m_blValid)&&
        (p_target->m_enuType > e_ES_SCHEDULE_TYPE_NONE)&&
        (p_target->m_enuType < e_ES_SCHEDULE_TYPE_MAX))
    {
        switch(p_target->m_enuOP)
        {
            case e_ES_SCHEDULE_OP_ALL:
            {
                //无条件计划（执行间隔生效）
                if((true == p_target->m_struSetTime.m_blInvertValid)&&
                    (false == p_target->m_struSetTime.m_blStartStopSetValid)&&
                    (false == p_target->m_struSetTime.m_blDaySetValid)&&
                    (false == p_target->m_struSetTime.m_blWeekDaySetValid)&&
                    (false == p_target->m_struSetTime.m_blMonthSetValid)&&
                    (false == p_target->m_struSetTime.m_blYearSetValid))
                {
                    if(p_target->m_struSetTime.u32SetOpInvertSec!=0)
                    {
                        return true;
                    }
                }
            }
                break;
            case e_ES_SCHEDULE_OP_ONCE:
            {
                //单次计划(执行的年月日开始时间必须有效)
                if((false == p_target->m_struSetTime.m_blInvertValid)&&
                    (true == p_target->m_struSetTime.m_blStartStopSetValid)&&
                    (true == p_target->m_struSetTime.m_blDaySetValid)&&
                    (false == p_target->m_struSetTime.m_blWeekDaySetValid)&&
                    (true == p_target->m_struSetTime.m_blMonthSetValid)&&
                    (true == p_target->m_struSetTime.m_blYearSetValid))
                {
                    if((p_target->m_struSetTime.u32SetDay > 0)&&
                        (p_target->m_struSetTime.uni_SetMonth.m_u16MonthSetValue > 0)&&
                        (p_target->m_struSetTime.u16SetYear > 0))
                    {
                        return true;
                    }
                }
            }
                break; 
            case e_ES_SCHEDULE_OP_LOOP_SINGLE:
            {
                //循环单次计划（日期有效开始时间有效）
                if((false == p_target->m_struSetTime.m_blInvertValid)&&
                    (true == p_target->m_struSetTime.m_blStartStopSetValid)&&
                    (true == p_target->m_struSetTime.m_blDaySetValid))
                {
                    if(p_target->m_struSetTime.u32SetDay>0)
                    {
                        return true;
                    }
                }
            }
                break; 
            case e_ES_SCHEDULE_OP_LOOP_CONTINUE:
            {
                //循环持续计划（日期有效，开始时间有效，执行间隔有效，有跨天可能）
                if((true == p_target->m_struSetTime.m_blInvertValid)&&
                    (true == p_target->m_struSetTime.m_blStartStopSetValid)&&
                    (true == p_target->m_struSetTime.m_blDaySetValid))
                {
                    if((p_target->m_struSetTime.u32SetOpInvertSec>0)&&
                        (p_target->m_struSetTime.u32SetDay>0))
                    {
                        return true;
                    }
                }
            }
                break; 
            case e_ES_SCHEDULE_OP_AUTO:
            {
                //自动触发计划（根据设定的自动判定回调函数触发开始和结束）
                if(true == p_target->m_struSetTime.m_blInvertValid)
                {
                    if(0 == p_target->m_struSetTime.u32SetOpInvertSec)
                    {
                        return false;
                    }
                }
                if(true == p_target->m_struSetTime.m_blDaySetValid)
                {
                    if(p_target->m_struSetTime.u32SetDay==0)
                    {
                        return false;
                    }
                }
                if((NULL == p_target->EsScheduleAutoDecideStartHandle)||
                    (NULL == p_target->EsScheduleAutoDecideStopHandle))
                {
                    return false;
                }
                return true;
            }
                    //break;
            default:
            {
                LOCAL_DEBUG("ES_M:: EsManageScheduleTargetCheck op type error == %d\r\n",p_target->m_enuOP);
                return false;
            }
                //break;
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ScheTargetTimeIsInForOpAll
 * @brief Inner Functions:Whether the unconditional sche reaches the execution condition (execution interval takes effect)
 * @parm[in] p_sche:dest schedule point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：无条件计划是否到达执行条件（执行间隔生效）
static bool ScheTargetTimeIsInForOpAll(ENUM_ES_SCHEDULE_STATE_T *p_sche)
{
    LOCAL_DEBUG("ES_M::EsManageScheduleTargetTimeIsIn \r\n");
    if(NULL != p_sche)
    {
        if((true == p_sche->m_enuTarget.m_blValid)&&
            (true == p_sche->m_enuTarget.m_blSwitch))
        {
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blInvertValid)
            {
                if(p_sche->m_u32WaitTimeSecCount >= p_sche->m_enuTarget.m_struSetTime.u32SetOpInvertSec)
                {
                    p_sche->m_u32WaitTimeSecCount = 1;
                    return true;
                }
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ScheTargetTimeIsInForOnce
 * @brief Inner Functions:Whether the execution condition of a single sche has been reached (whether the start time of execution has been reached)
 * @parm[in] p_sche:dest schedule point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：单次计划是否到达执行条件(执行的年月日开始时间是否达到)
static bool ScheTargetTimeIsInForOnce(ENUM_ES_SCHEDULE_STATE_T *p_sche)
{
    LOCAL_DEBUG("ES_M::ScheTargetTimeIsInForOnce \r\n");
    if(p_sche!=NULL)
    {
        if((true == p_sche->m_enuTarget.m_blValid)&&
            (true == p_sche->m_enuTarget.m_blSwitch))
        {
            if(true == p_sche->m_enuTarget.m_struSetTime.u16SetYear)
            {
                if(p_sche->m_enuTarget.m_struSetTime.u16SetYear!= es_sys_api.get_year())
                {
                    return false;
                }
            }    
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blMonthSetValid)
            {
                if(0==((p_sche->m_enuTarget.m_struSetTime.uni_SetMonth.m_u16MonthSetValue)&((uint16_t)(1<< es_sys_api.get_month()))))
                {
                    return false;
                }
            }
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blWeekDaySetValid)
            {
                if(0==((p_sche->m_enuTarget.m_struSetTime.uni_SetWeekDay.m_u8WeekSetValue)&(1<<es_sys_api.get_week())))
                {
                    return false;
                }
            }
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blDaySetValid)
            {
                if((p_sche->m_enuTarget.m_struSetTime.u32SetDay)&(1<<es_sys_api.get_day()))
                {
                    return false;
                }
            }
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blStartStopSetValid)
            {
                if((p_sche->m_enuTarget.m_struSetTime.u8StartH > es_sys_api.get_hour())||
                    ((p_sche->m_enuTarget.m_struSetTime.u8StartH == es_sys_api.get_hour())&&
                    (p_sche->m_enuTarget.m_struSetTime.u8StartM > es_sys_api.get_min()))||
                    ((p_sche->m_enuTarget.m_struSetTime.u8StartH == es_sys_api.get_hour())&&
                    (p_sche->m_enuTarget.m_struSetTime.u8StartM == es_sys_api.get_min())&&
                    (p_sche->m_enuTarget.m_struSetTime.u8StartS > es_sys_api.get_sec())))
                {
                    return false;
                }
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

/**
 ***************************************************************************
 * @name ScheTargetTimeIsInForLoopSingle
 * @brief Inner Functions:Whether the execution condition of a single sche has been reached (whether the start time of execution has been reached)
 * @parm[in] p_sche:dest schedule point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：循环单次计划是否到达执行条件(日期有效，开始时间有效)
static bool ScheTargetTimeIsInForLoopSingle(ENUM_ES_SCHEDULE_STATE_T *p_sche)
{
    //LOCAL_DEBUG("ES_M::ScheTargetTimeIsInForLoopSingle \r\n");
    if(NULL != p_sche)
    {
        if((true == p_sche->m_enuTarget.m_blValid)&&
            (true == p_sche->m_enuTarget.m_blSwitch))
        {
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blMonthSetValid)
            {
                if(0==((p_sche->m_enuTarget.m_struSetTime.uni_SetMonth.m_u16MonthSetValue)&((uint16_t)(1<< es_sys_api.get_month()))))
                {
                    return false;
                }
            }
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blWeekDaySetValid)
            {
                if(0==((p_sche->m_enuTarget.m_struSetTime.uni_SetWeekDay.m_u8WeekSetValue)&(1<<es_sys_api.get_week())))
                {
                    return false;
                }
            }
            if(false == EsManageScheduleTargetContinueTimeAndDayIsIn(p_sche))
            {
                return false;
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

/**
 ***************************************************************************
 * @name ScheTargetTimeIsInForLoopContinue
 * @brief Inner Functions:Whether the cycle persistence sche reaches the execution condition (date is valid, start time is valid, execution interval is valid, may cross the day)  
 * @parm[in] p_sche:dest schedule point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：循环持续计划是否到达执行条件(日期有效，开始时间有效，执行间隔有效，有跨天可能)
static bool ScheTargetTimeIsInForLoopContinue(ENUM_ES_SCHEDULE_STATE_T *p_sche)
{
    //LOCAL_DEBUG("ES_M::ScheTargetTimeIsInForLoopSingle \r\n");
    if(p_sche!=NULL)
    {
        if((true == p_sche->m_enuTarget.m_blValid)&&
            (true == p_sche->m_enuTarget.m_blSwitch))
        {
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blWeekDaySetValid)
            {
                if(0==((p_sche->m_enuTarget.m_struSetTime.uni_SetWeekDay.m_u8WeekSetValue)&(1<<es_sys_api.get_week())))
                {
                    return false;
                }
            }
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blDaySetValid)
            {
                if((p_sche->m_enuTarget.m_struSetTime.u32SetDay)&(1<<es_sys_api.get_day()))
                {
                    return false;
                }
            }
            if(true == p_sche->m_enuTarget.m_struSetTime.m_blStartStopSetValid)
            {
                if((p_sche->m_enuTarget.m_struSetTime.u8StartH > es_sys_api.get_hour())||
                    ((p_sche->m_enuTarget.m_struSetTime.u8StartH == es_sys_api.get_hour())&&
                    (p_sche->m_enuTarget.m_struSetTime.u8StartM > es_sys_api.get_min()))||
                    ((p_sche->m_enuTarget.m_struSetTime.u8StartH == es_sys_api.get_hour())&&
                    (p_sche->m_enuTarget.m_struSetTime.u8StartM == es_sys_api.get_min())&&
                    (p_sche->m_enuTarget.m_struSetTime.u8StartS > es_sys_api.get_sec())))
                {
                    return false;
                }
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

/**
 ***************************************************************************
 * @name EsManageScheduleTargetContinueTimeAndDayIsIn
 * @brief Inner Functions:Whether the plan is on target time
 * @parm[in] p_sche:dest schedule point
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：  continue计划是否在目标时间内(判断是否跨天)
static bool EsManageScheduleTargetContinueTimeAndDayIsIn(ENUM_ES_SCHEDULE_STATE_T *p_sche)
{
    //检查计划的天设定，是否跨天
    if((p_sche->m_enuTarget.m_struSetTime.u8StartH > p_sche->m_enuTarget.m_struSetTime.u8EndH)||
        ((p_sche->m_enuTarget.m_struSetTime.u8StartH == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
        (p_sche->m_enuTarget.m_struSetTime.u8StartM >= p_sche->m_enuTarget.m_struSetTime.u8EndM))||
        ((p_sche->m_enuTarget.m_struSetTime.u8StartH == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
        (p_sche->m_enuTarget.m_struSetTime.u8StartM == p_sche->m_enuTarget.m_struSetTime.u8EndM)&&
        (p_sche->m_enuTarget.m_struSetTime.u8StartS == p_sche->m_enuTarget.m_struSetTime.u8EndS)))
    {
        //跨天
        if(true == p_sche->m_enuTarget.m_struSetTime.m_blDaySetValid)
        {
            //对天时间进行判定
            if((uint8_t)(p_sche->m_enuTarget.m_struSetTime.u32SetDay)&(1<<es_sys_api.get_day()))
            {
                //开始时间判断
                if((es_sys_api.get_hour() > p_sche->m_enuTarget.m_struSetTime.u8StartH)||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                    (es_sys_api.get_min() > p_sche->m_enuTarget.m_struSetTime.u8StartM))||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                    (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8StartM)&&
                    (es_sys_api.get_sec() >= p_sche->m_enuTarget.m_struSetTime.u8StartS)))
                {
                    return true;
                }
            }
            else
            {
                uint8_t prev_day;
                prev_day = es_sys_api.get_yestoday_day();
                if((uint8_t)(p_sche->m_enuTarget.m_struSetTime.u32SetDay)&(1<<(prev_day)))
                {
                    //结束时间判断
                    if((es_sys_api.get_hour() < p_sche->m_enuTarget.m_struSetTime.u8EndH)||
                        ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                        (es_sys_api.get_min() < p_sche->m_enuTarget.m_struSetTime.u8EndM))||
                        ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                        (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8EndM)&&
                        (es_sys_api.get_sec() <= p_sche->m_enuTarget.m_struSetTime.u8EndS)))
                    {
                        return true;
                    }
                }
            }
        }
        else
        {
            //没有设定固定时间，天天触发
            //开始结束时间判断
            if(((es_sys_api.get_hour() > p_sche->m_enuTarget.m_struSetTime.u8StartH)||
                ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                (es_sys_api.get_min() > p_sche->m_enuTarget.m_struSetTime.u8StartM))||
                ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8StartM)&&
                (es_sys_api.get_sec() >= p_sche->m_enuTarget.m_struSetTime.u8StartS)))||
                    ((es_sys_api.get_hour() < p_sche->m_enuTarget.m_struSetTime.u8EndH)||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                    (es_sys_api.get_min() < p_sche->m_enuTarget.m_struSetTime.u8EndM))||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                    (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8EndM)&&
                    (es_sys_api.get_sec() <= p_sche->m_enuTarget.m_struSetTime.u8EndS))))
            {
                return true;
            }
        }
    }
    else
    {
        //没跨天
        if(true == p_sche->m_enuTarget.m_struSetTime.m_blDaySetValid)
        {
            //对天时间进行判定
            if((uint8_t)(p_sche->m_enuTarget.m_struSetTime.u32SetDay)&(1<<es_sys_api.get_day()))
            {
                //开始结束时间判断
                if(((es_sys_api.get_hour() > p_sche->m_enuTarget.m_struSetTime.u8StartH)||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                    (es_sys_api.get_min() > p_sche->m_enuTarget.m_struSetTime.u8StartM))||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                    (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8StartM)&&
                    (es_sys_api.get_sec() >= p_sche->m_enuTarget.m_struSetTime.u8StartS)))&&
                    ((es_sys_api.get_hour() < p_sche->m_enuTarget.m_struSetTime.u8EndH)||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                    (es_sys_api.get_min() < p_sche->m_enuTarget.m_struSetTime.u8EndM))||
                    ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                    (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8EndM)&&
                    (es_sys_api.get_sec() <= p_sche->m_enuTarget.m_struSetTime.u8EndS))))
                {
                    return true;
                }
            }
        }
        else
        {
            //没有设定固定时间，天天触发
            //开始结束时间判断
            if(((es_sys_api.get_hour() > p_sche->m_enuTarget.m_struSetTime.u8StartH)||
                ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                (es_sys_api.get_min() > p_sche->m_enuTarget.m_struSetTime.u8StartM))||
                ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8StartH)&&
                (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8StartM)&&
                (es_sys_api.get_sec() >= p_sche->m_enuTarget.m_struSetTime.u8StartS)))&&
                ((es_sys_api.get_hour() < p_sche->m_enuTarget.m_struSetTime.u8EndH)||
                ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                (es_sys_api.get_min() < p_sche->m_enuTarget.m_struSetTime.u8EndM))||
                ((es_sys_api.get_hour() == p_sche->m_enuTarget.m_struSetTime.u8EndH)&&
                (es_sys_api.get_min() == p_sche->m_enuTarget.m_struSetTime.u8EndM)&&
                (es_sys_api.get_sec() <= p_sche->m_enuTarget.m_struSetTime.u8EndS))))
            {
                return true;
            }
        }
    }
    return false;
}

/**
 ***************************************************************************
 * @name ExtEsManageScheduleQueueFindIndex
 * @brief Inner Functions:Whether the plan is on target time
 * @parm[in] find_type:dest schedule point;index_num:return index
 *
 * @return true:sucess,false:faild
 ***************************************************************************
 */
 //内部函数：  寻找计划在事件队列位置下标
static bool ExtEsManageScheduleQueueFindIndex(ENUM_ES_SCHEDULE_TARGET_TYPE_S find_type,uint16_t *index_num)
{
    LOCAL_DEBUG("ES_M::ExtEsManageScheduleQueueFindIndex ID==%d\r\n",find_type);
    if((NULL != index_num)&&
        (find_type > e_ES_SCHEDULE_NONE)&&
       (find_type < e_ES_SCHEDULE_TYPE_MAX))
    {
        *index_num = 0;
        for(uint16_t i = 0;i<ES_SCHEDULE_QUEUE_MAX_NUM;i++)
        {
            if((false == g_m_es_schedule[i].m_blIsEmpty)&&
                (g_m_es_schedule[i].m_enuTarget.m_enuType == find_type))
            {
                LOCAL_DEBUG("ES_M::find Schedule successful index == %d\r\n",i);
                *index_num = i;
                return true;
            }
        }
    }
    return false;
}

/***********************************************************************************/
//                  test Function declaration           
/***********************************************************************************/
/**
 ***************************************************************************
 * @name ExtEsManageDebugAllEs
 * @brief test Functions:print all es
 * @parm[in] none
 *
 * @return none
 ***************************************************************************
 */
 //测试接口：打印所有事件队列
/*void ExtEsManageDebugAllEs(void)
{
    LOCAL_DEBUG("ES_M::ExtEs--output--EVENT \r\n");
    for(uint16_t i =0 ;i < ES_EVENT_QUEUE_MAX_NUM;i++)
    {
        if(false == g_m_es_event[i].m_blIsEmpty)
        {
            //LOCAL_DEBUG("ES_M::[%d] event type = %d\r\n",i,g_m_es_event[i].m_enuTarget.m_enuType);
            switch(g_m_es_event[i].m_enuTarget.m_enuType)
            {
                case e_ES_EVENT_TYPE_NONE:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_NONE \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_GLOBAL_DAY_HR:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_GLOBAL_REST_HR_OP \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_SINGLE_TEST_HR:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_SINGLE_TEST_HR \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_GLOBAL_DAY_SPO2:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_GLOBAL_DAY_SPO2 \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_SINGLE_TEST_SPO2:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_SINGLE_TEST_SPO2 \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_SINGLE_TEST_RAWDATA:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_SINGLE_TEST_RAWDATA \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_TEST_01:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_TEST_01 \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_TEST_02:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_TEST_02 \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_TEST_03:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_TEST_03 \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_TEST_04:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_TEST_04 \r\n",i);
                    break;
                case e_ES_EVENT_TYPE_TEST_05:
                    LOCAL_DEBUG("ES_M::[%d] event type = e_ES_EVENT_TYPE_TEST_05 \r\n",i);
                    break;
                default:
                    LOCAL_DEBUG("ES_M::[%d] event type = error type \r\n",i);
                    break;
            }
            LOCAL_DEBUG("ES_M::[%d] event op type = %d\r\n",i,g_m_es_event[i].m_enuTarget.m_enuOP);
            LOCAL_DEBUG("ES_M::[%d] event set time = %d\r\n",i,g_m_es_event[i].m_enuTarget.m_u32SetTimeLong);
            LOCAL_DEBUG("ES_M::[%d] event priority = %d\r\n",i,g_m_es_event[i].m_enuPriority);
            LOCAL_DEBUG("ES_M::[%d] event state = %d\r\n",i,g_m_es_event[i].m_enuState);
            LOCAL_DEBUG("ES_M::[%d] event run time = %d\r\n",i,g_m_es_event[i].m_u32OpTimeSecCount);
        }
    }

    for(uint16_t i =0 ;i < ES_SCHEDULE_QUEUE_MAX_NUM;i++)
    {
        if(false == g_m_es_schedule[i].m_blIsEmpty)
        {
            //LOCAL_DEBUG("ES_M::[%d] schedule target type = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_enuType);
            switch(g_m_es_schedule[i].m_enuTarget.m_enuType)
            {
                case e_ES_SCHEDULE_TYPE_NONE:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_NONE \r\n",i);
                    break;
                case e_ES_SCHEDULE_TYPE_SLEEP_SPO2_SWITCH:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_SLEEP_SPO2_SWITCH \r\n",i);
                    break;
                case e_ES_SCHEDULE_TYPE_TEST_01:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_TEST_01 \r\n",i);
                    break;
                case e_ES_SCHEDULE_TYPE_TEST_02:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_TEST_02 \r\n",i);
                    break;
                case e_ES_SCHEDULE_TYPE_TEST_03:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_TEST_03 \r\n",i);
                    break;
                case e_ES_SCHEDULE_TYPE_TEST_04:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_TEST_04 \r\n",i);
                    break;
                case e_ES_SCHEDULE_TYPE_TEST_05:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = e_ES_SCHEDULE_TYPE_TEST_05 \r\n",i);
                    break;
                default:
                    LOCAL_DEBUG("ES_M::[%d] schedule type = error type \r\n",i);
                    break;
            }
            LOCAL_DEBUG("ES_M::[%d] schedule target op type = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_enuOP);
            LOCAL_DEBUG("ES_M::[%d] schedule target vaild = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_blValid);
            LOCAL_DEBUG("ES_M::[%d] schedule target switch = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_blSwitch);

            if(true == g_m_es_schedule[i].m_enuTarget.m_struSetTime.m_blInvertValid)
            {
                LOCAL_DEBUG("ES_M::[%d] target invert time = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u32SetOpInvertSec);
            }
            if(true == g_m_es_schedule[i].m_enuTarget.m_struSetTime.m_blStartStopSetValid)
            {
                LOCAL_DEBUG("ES_M::[%d] target start hour = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u8StartH);
                LOCAL_DEBUG("ES_M::[%d] target start min = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u8StartM);
                LOCAL_DEBUG("ES_M::[%d] target start sec = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u8StartS);
                LOCAL_DEBUG("ES_M::[%d] target end hour = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u8EndH);
                LOCAL_DEBUG("ES_M::[%d] target end min = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u8EndM);
                LOCAL_DEBUG("ES_M::[%d] target end sec = %d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u8EndS);
            }
            if(true == g_m_es_schedule[i].m_enuTarget.m_struSetTime.m_blDaySetValid)
            {
                LOCAL_DEBUG("ES_M::[%d] target op day = 0x%0x\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u32SetDay);
            }
            if(true == g_m_es_schedule[i].m_enuTarget.m_struSetTime.m_blWeekDaySetValid)
            {
                LOCAL_DEBUG("ES_M::[%d] target op weekday = 0x%0x\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.uni_SetWeekDay.m_u8WeekSetValue);
            }
            if(true == g_m_es_schedule[i].m_enuTarget.m_struSetTime.m_blMonthSetValid)
            {
                LOCAL_DEBUG("ES_M::[%d] target op month = 0x%0x\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.uni_SetMonth.m_u16MonthSetValue);
            }
            if(true == g_m_es_schedule[i].m_enuTarget.m_struSetTime.m_blYearSetValid)
            {
                LOCAL_DEBUG("ES_M::[%d] target op year = %0d\r\n",i,g_m_es_schedule[i].m_enuTarget.m_struSetTime.u16SetYear);
            }
            LOCAL_DEBUG("ES_M::[%d] schedule priority = %d\r\n",i,g_m_es_schedule[i].m_enuPriority);
            LOCAL_DEBUG("ES_M::[%d] schedule state = %d\r\n",i,g_m_es_schedule[i].m_enuState);
            LOCAL_DEBUG("ES_M::[%d] schedule run time = %d\r\n",i,g_m_es_schedule[i].m_u32OpTimeSecCount);
        }
    }
    
}
*/

/*****************************************************************************/

